Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a list with only two 1s and other 0s of the given length?

Tags:

list

prolog

clpfd

I have to generate lists that consist of 2 '1's and other elements are '0's. I tried the following code but it does not work:

count([], _, 0).
count([X|T], X, Y) :- count(T, X, Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).

two(X) :- count(X, 1, Counter), Counter =:= 2.

Querying length(Vs, 4), Vs ins 0..1, two(Vs). gives nothing.

How to generate such lists properly? I expect to get something like [1, 1, 0, 0], [1, 0, 1, 0] ... [0, 0, 1, 1].

like image 667
Bakhanov A. Avatar asked Oct 21 '25 15:10

Bakhanov A.


2 Answers

twoones(Bs) :-
   Bs ins 0..1,
   sum(Bs, #=, 2).

?- length(Bs,4), twoones(Bs).
   Bs = [_A,_B,_C,_D], clpz:(_A+_B+_C+_D#=2),
      clpz:(_A in 0..1), clpz:(_B in 0..1),
      clpz:(_C in 0..1), clpz:(_D in 0..1).
?- length(Bs,4), twoones(Bs), labeling([], Bs).
   Bs = [0,0,1,1]
;  Bs = [0,1,0,1]
;  Bs = [0,1,1,0]
;  ... .

Here, I am using library(clpz) which is the successor to library(clpfd). For simple examples as this, there is not much of a difference.

like image 62
false Avatar answered Oct 24 '25 09:10

false


A grammar is quite a natural way of specifying a list pattern:

two --> [1], one ; [0], two.
one --> [1], zeros ; [0], one.
zeros --> [] ; [0], zeros.

Example call:

?- length(Xs, 3), phrase(two, Xs, []).
Xs = [1, 1, 0]
Yes (0.00s cpu, solution 1, maybe more)
Xs = [1, 0, 1]
Yes (0.00s cpu, solution 2, maybe more)
Xs = [0, 1, 1]
Yes (0.00s cpu, solution 3, maybe more)
No (0.00s cpu)
like image 23
jschimpf Avatar answered Oct 24 '25 09:10

jschimpf