I\'ve been having trouble trying to split numbers into lists using Prolog, e.g. 123456 becomes [1,2,3,4,5,6]
.
Can you please help me work out how to do
the builtins available are ISO standard:
?- number_codes(123456,X),format('~s',[X]).
123456
X = [49, 50, 51, 52, 53, 54].
?- number_chars(123456,X),format('~s',[X]).
123456
X = ['1', '2', '3', '4', '5', '6'].
I also have some very old code I developed for my interpreter. :=
must be renamed is
to run with standard Prologs. But then you are best served from above builtins...
itoa(N, S) :-
N < 0, !,
NN := 0 - N,
iptoa(NN, SR, _),
reverse(SR, SN),
append("-", SN, S).
itoa(N, S) :-
iptoa(N, SR, _),
reverse(SR, S).
iptoa(V, [C], 1) :-
V < 10, !,
C := V + 48.
iptoa(V, [C|S], Y) :-
M := V / 10,
iptoa(M, S, X),
Y := X * 10,
C := V - M * 10 + 48.
edit here the additional call required to get numbers:
?- number_codes(123456,X), maplist(plus(48),Y,X).
X = [49, 50, 51, 52, 53, 54],
Y = [1, 2, 3, 4, 5, 6].
You could first create a reverse list:
//Base step
splitRev(0,[]).
//Recursive step
splitRev(N,[A|As]) :- N1 is floor(N/10), A is N mod 10, splitRev(N1,As).
The recursive step works like this:
N1 is floor(N/10)
divides N by 10 and rounds it down. So 538 becomes 53.8 becomes 53. It cuts off the last digit.
A is N mod 10
takes the remainder of N divided by 10. 538 mod 10 equals 8. So you get only the last digit.
Now for splitting the list you only need to reverse the list created by splitRev/2. So predicate split/2 is defined as:
split(N,L1) :- splitRev(N,L2), reverse(L1,L2).
Note that reverse/2 is a built-in predicate.
I hope this helps!