Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog converting integer to a list of digit

I want to write a predicate that an integer and a list of digits, and succeed if Digits contain the digits of the integer in the proper order, i.e:

?-digit_lists( Num, [1,2,3,4] ).
[Num == 1234].

Here is what I have so far:

my_digits( 0, [] ).
my_digits(N,[A|As]) :- N1 is floor(N/10), A is N mod 10, my_digits(N1, As).
like image 293
Duc Hai Avatar asked Dec 20 '22 07:12

Duc Hai


2 Answers

I think this is easier:

numToList(NUM,[LIST|[]]):-
   NUM < 10,
   LIST is NUM,
   !.
numToList(NUM,LIST):-
   P is NUM // 10,
   numToList(P,LIST1),
   END is (NUM mod 10), 
   append(LIST1,[END] ,LIST).
like image 82
user8354592 Avatar answered Jan 18 '23 22:01

user8354592


As already suggested, consider using finite domain constraints:

:- use_module(library(clpfd)).

number_digits(Number, 0, [Number]) :- Number in 0..9.
number_digits(Number, N, [Digit|Digits]) :-
        Digit in 0..9,
        N #= N1 + 1,
        Number #= Digit*10^N + Number1,
        Number1 #>= 0,
        N #> 0,
        number_digits(Number1, N1, Digits).

This predicate can be used in all directions. Examples with either argument instantiated:

?- number_digits(215, _, Ds).
Ds = [2, 1, 5] ;
false.

?- number_digits(N, _, [4,3,2,1]).
N = 4321 ;
false.

And two more general queries:

?- number_digits(N, _, [A,B]).
N in 10..99,
_G2018+B#=N,
_G2018 in 10..90,
A*10#=_G2018,
A in 0..9,
B in 0..9 ;
false.

?- number_digits(N, _, Ds).
Ds = [N],
N in 0..9 ;
Ds = [_G843, _G846],
N in 0..99,
_G870+_G846#=N,
_G870 in 0..90,
_G843*10#=_G870,
_G843 in 0..9,
_G846 in 0..9 ;
etc.
like image 34
mat Avatar answered Jan 18 '23 21:01

mat