Reputation: 2262
I want to generate a list with all the numbers abc
, where a = c
and b >= a + c
.
I know how to generate the numbers, but I do not know how to add them to the list because I can not do something like L = [Number|L]
.
I don't know how to define the add
predicate... or should I do it in another way?
I have tried defining it as add(Nr, L, [Nr|L]).
, but I have no idea of what to do after that.
c(0). c(1). c(2). c(3). c(4). c(5). c(6). c(7). c(8). c(9).
bts(L, Lr) :- c(A), A =\= 0, c(C), A =:= C, c(B), C =\=9, B >= A + C,
Nr is A * 100 + B * 10 + C,
add(......).
solve(L) :- bts([], L).
The output should be:
L=[121,131,141,151,161,171,181,191,242,252,262,272,282,292,363,373,383,393,484,494]
Upvotes: 0
Views: 97
Reputation: 2262
This is the solution I found:
bts(1000, []) :- !.
bts(Nr, L) :-
N is Nr + 1,
bts(N, X),
once(((number_chars(Nr, [H1, H2, H3]), number_chars(A, [H1]), number_chars(C, [H3]),
A =:= C, number_chars(B, [H2]), B >= A + C,
L = [Nr|X]);
L = X)).
solve(L) :- bts(100, L).
Upvotes: 1
Reputation: 60014
a simple application of findall/3 and between/3
abc(Ns) :- findall(N, (between(1,9,A),between(1,9,B),C=A,B>=A+C,N is A * 100 + B * 10 + C), Ns).
Upvotes: 1
Reputation: 40768
You are on the right track. Here are two small tips:
findall/3
and setof/3
to collect all solutions into a list of solutions.In total, my recommendation is to do it similar to the following:
abc(Ls) :- Ls = [A,B,C], A #= C, A #\= 0, C #\= 9, B #>= A + C, Ls ins 0..9.
We can now try the most general query to see what solutions look like in general:
?- abc(Ls). Ls = [_940, _946, _940], _940 in 1..4, 2*_940#=<_946, _946 in 2..9.
This is of course not very useful, but it at least tells us that our relation terminates and is deterministic.
This means that so-called labeling, which is the search for concrete solutions will also terminate. That is a very nice property, because it means that the search will always terminate, even if it may take a long time.
In this case, the search is of course trivial, and we can use for example label/1
to enumerate solutions:
?- abc(Ls), label(Ls). Ls = [1, 2, 1] ; Ls = [1, 3, 1] ; Ls = [1, 4, 1] ; Ls = [1, 5, 1] ; etc.
Now, to obtain the results you want, we will use findall/3
to collect all solutions into a list:
?- abc(Ls), findall(N, (label(Ls), atomic_list_concat(Ls,A),atom_number(A,N)), Ns). Ls = [_774, _780, _774], Ns = [121, 131, 141, 151, 161, 171, 181, 191, 242|...], _774 in 1..4, 2*_774#=<_780, _780 in 2..9.
I have also taken the liberty to apply a small transformation to each solution, so that you get the desired result immediately.
The formalism I am applying here is called CLP(FD), and the exact details for invoking this mechanism differ slightly between available Prolog systems. Check your system's manual for more information, and see also clpfd.
Upvotes: 1