Я построил предикат, который преобразует римские цифры в арабские. Единственная проблема в том, что предикат ограничен: если я хочу преобразовать более 3 арабских цифр одновременно, это больше не работает.
Вот как должен работать предикат:
?- convert([v,i,i],Arabic).
Arabic = 7.
Мое решение до сих пор:
tran([],0).
tran(i,1).
tran(v,5).
tran(x,10).
convert([],X) :- X is 0, !.
convert([T],X) :- tran(T,E), X is E,!.
convert([T|Ts],X) :- tran(T,E), tran(Ts,Es), X is E+Es,!.
convert([T,Ts,Tss],X) :- tran(T,E), tran(Ts,Es), tran(Tss,Ess), X is E+Es+Ess.
Я знаю, почему предикат не работает с более чем 3 числительными, и я мог бы также расширить предикат convert, но с тем же шаблоном, как показано выше.
Как сделать предикат convert более «общим» (чтобы он мог работать независимо от количества числительных)? Или у вас есть другие идеи, как написать предикат? Спасибо :)
convert([],X) :-...
доconvert([],0).
иconvert([T],X) :- ...
доconvert([T],E) :- tran(T,E).
Обратите внимание, что правила для римских цифр (см. en.wikipedia.org /wiki/Roman_numerals) зависят от того, следует ли более высокое значение за более низким значением. Таким образом, ваш предикатconvert
должен будет просмотреть два последовательных значения, чтобы сделать выбор, например,convert([X,Y|T], Value) :- X < Y, % add in Y-X
. Я бы также рекомендовал сначала преобразовать список в числа, а затем оперировать, чтобы упростить арифметику и сравнения. - person lurker   schedule 04.02.2014