Пролог программа со списками
В качестве домашнего задания я должен решить следующую задачу в турбо-прологе: "Определите произведение числа, представленного в виде цифр в списке, на заданную цифру. Например: [1 9 3 5 9 9] * 2 -> [3 8 7 1 9 8] " .
Мой подход к решению этой проблемы заключается в том, что я сначала вычисляю продукт, а затем помещаю его цифры в список. Только я не могу понять эту последнюю часть. Вот мой исходный код:
домены
list=integer*
предикаты
length(list,integer)
powerten(integer,integer)
product(integer,list,integer) /* this predicate computes the product */
/* the product,powerten and length are taken care of */
addDigit(integer,list) /* this predicate should decompose the number in its digits and put them in the list */
productList(integer,list,list)
статьи
length([],0).
length([_|T],L):-
length(T,L1),
L=L1+1.
powerten(0,1):-!.
powerten(L,N):-
L1=L-1,
powerten(L1,N1),
N=N1*10.
product(_,[],0):-!.
product(NR,[H|T],RESULT ):-
length([H|T],LEN),
L2=LEN-1,
powerten(L2,N),
product(NR,T,R1),
RESULT=R1+H*N*NR.
addDigit(0,[]):-!.
addDigit(NR,[NR|_]):-
NR>0,
DIGIT = NR MOD 10,
NR1=NR DIV 10,
addDigit(NR1,_).
productList(NR,L1,L2):-
/* this is the "main" predicate . Its arguments are NR - the first factor, L1- the
initial list, whose digits make the second factor, L2 - the result list which
contains the digits of he result */
product(NR,L1,RESULT),
addDigit(RESULT,L2).
Как видите, все хорошо до предиката addDigit. Я просто не могу найти способ добавить цифры продукта в окончательный список. Может кто-нибудь помочь мне с решением? Благодарю.
2 ответа
Это кажется сложным для меня. Проблема в том, чтобы сделать умножение в длинных формах так, как это делалось бы на бумаге. Если вы сначала перевернуть список (используя встроенный reverse/2
предикат), все становится намного проще:
%--------------------------------------------------------------%
% Mult/3: multiply a integer, represented as a list of digits, %
% by an integer value N, producing an integer, also %
% represented as a lsit of digits. %
%--------------------------------------------------------------%
multiply( Ds , N , Result) :-
reverse(Ds,Rs) ,
multiply( Rs , N , 0 , T ) ,
reverse( T , Result )
.
%
% the worker predicate that does all the work
%
multiply( [] , _ , C , [] ) :- % if the list is exhausted
C =< 0 % and the carry is 0,
. % we're done. C'est fini.
multiply( [] , _ , C , [C] ) :- % if the list is exhausted
C > 0 , % and the carry is 1-9, then
C < 10 % The last digit in the result is the carry
. % We're done. C'est fini.
multiply( [] , _ , C , [R|Rs] ) :- % If the list is exhausted,
C >= 10 , % and the carry is 10+,
R is C rem 10 , % the next digit in the result is the carry modulo 10
Q is C div 10 , % take the quotient
multiply( [] , _ , Q , Rs ) % and recurse down with the quotient as the carry
. %
multiply( [D|Ds] , N , C , [R|Rs] ) :- % if the list is NOT exhausted,
T is D*N + C , % compute the product for this digit
R is T rem 10 , % the next digit in the result is that product modulo 10
Q is T div 10 , % the next carry is the quotient
multiply( Ds , N , Q , Rs ) % recurse down
. $ Easy!
addDigit мне кажется неправильным: вы используете только первое, а хвост не указан! пытаться
addDigit(NR,[DIGIT|Ns]):-
NR>0,
DIGIT = NR MOD 10,
NR1 = NR DIV 10,
addDigit(NR1, Ns).