Все двоичные числа с ровно n цифрами - PullRequest
0 голосов
/ 28 декабря 2011

Мне нужен предикат для создания всех двоичных чисел длиной N в списке.

Пример использования:

?- bins(2,L).
L = [[0,0], [0,1], [1,0], [1,1]].    % expected result

Ответы [ 3 ]

3 голосов
/ 13 августа 2015

Не нужно использовать findall/3!

Мы определяем bins/2 на основе , foldl/4, Пролог лямбда , if_/3и (#<)/3.

:- use_module(library(lambda)).
:- use_module(library(clpfd)).

bins(N,Zss) :-
   if_(N #< 1,
       ( N #= 0, Zss = [[]] ),
       ( N #= N0+1,
         bins(N0,Xss),
         foldl(\Bs^phrase(([[0|Bs]],[[1|Bs]])),Xss,Zss,[]))).

Пример использования:

?- bins(4,Zss).
Zss = [[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],
       [0,0,1,0],[1,0,1,0],[0,1,1,0],[1,1,1,0],
       [0,0,0,1],[1,0,0,1],[0,1,0,1],[1,1,0,1],
       [0,0,1,1],[1,0,1,1],[0,1,1,1],[1,1,1,1]].

Вот наиболее общий запрос:

?- bins(N,Zss).
  N = 0, Zss = [[]]
; N = 1, Zss = [[0],[1]]
; N = 2, Zss = [[0,0],[1,0],[0,1],[1,1]]
; N = 3, Zss = [[0,0,0],[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1],[1,1,1]]
...
2 голосов
/ 28 декабря 2011

Возможно, есть лучшие способы, но вот решение с использованием findall

bins(N,L) :-
    findall(Num,binary_number(N,Num),L).

binary_number(0,[]).
binary_number(N,[D|Ds]) :-
    N > 0,
    member(D,[0,1]),
    N1 is N - 1,
    binary_number(N1,Ds).
0 голосов
/ 28 декабря 2011

В качестве альтернативы:

member_(A, B) :- member(B, A).
bins(Size, Result) :-
    findall(L, (length(L, Size), maplist(member_([0, 1]), L)), Result).

Можно упростить с помощью модуля lambda :

bins(Size, Result) :-
    findall(L, (length(L, Size), maplist(\X^member(X, [0, 1]), L)), Result).
...