Prolog converts numbers to Roman numerals

I have this code that converts integers to Roman numerals. I need to add a function that compares an integer with a Roman input number and show if it tries or false, for example: Roman (V, 5). true

toroman(0). toroman(N) :- N < 4, put("I"), M is N - 1, toroman(M). toroman(N) :- N = 4, put("I"), put("V"). toroman(N) :- N = 5, put("V"). toroman(N) :- N < 9, put("V"), M is N - 5, toroman(M). toroman(N) :- N = 9, put("I"), put("X"). toroman(N) :- N < 40, put("X"), M is N - 10, toroman(M). toroman(N) :- N < 50, put("X"), put("L"), M is N - 40, toroman(M). toroman(N) :- N < 90, put("L"), M is N - 50, toroman(M). toroman(N) :- N < 100, put("X"), put("C"), M is N - 90, toroman(M). toroman(N) :- N < 400, put("C"), M is N - 100, toroman(M). toroman(N) :- N < 500, put("C"), put("D"), M is N - 400, toroman(M). toroman(N) :- N < 900, put("D"), put("D"), M is N - 500, toroman(M). toroman(N) :- N < 1000, put("C"), put("M"), M is N - 900, toroman(M). toroman(N) :- N < 4000, put("M"), M is N - 1000, toroman(M). roman(N) :- toroman(N). 
+6
source share
2 answers

Try differently stating the problem: write a grammar ( ) to relate the integer and the list of characters representing Roman numerals. Here is the start:

  : - use_module (library (clpfd)).

 roman (0) -> "".
 roman (N0) -> "I", {1 # = <N0, N0 # = <3, N1 # = N0-1}, roman (N1).

You can use it like this:

  ? - phrase (roman (3), L).
 L = "III";
 false

or

  ? - phrase (roman (N), "II").
 N = 2;
 false

or, if you don’t know what to ask, just ask the most general question:

  ? - phrase (roman (N), L).
 N = 0
 L = [];
 N = 1
 L = "I";
 N = 2
 L = "II";
 N = 3,
 L = "III";
 false

To get the answers compactly, like L = "III" , use :- set_prolog_flag(double_quotes,chars). More on this.

+5
source

You should change your toroman/1 procedure to something like toroman/2 , which returns a Roman numeral instead of printing it. A.

Then you can easily compare the Roman numeral with the result of calling toroman/2 into an integer.

Please note that your current procedure will loop until received if you return to another solution. You must either protect each sentence that recursively calls itself to recurs only if the call parameter is non-negative or add a check that is not safe as the first sentence, for example:

 roman(N):- N < 0, !, fail. 

After changing the torana / 1, to return to the Roman literal, you will get something like this (just change the bit of your code to return the literal as the second argument):

 toroman(N, _):- N < 0, !, fail. toroman(0, []). toroman(N, ['I'|Roman]) :- N < 4, M is N - 1, toroman(M, Roman). toroman(4, ['IV']). toroman(5, ['V']). toroman(N, ['V'|Roman]) :- N < 9, M is N - 5, toroman(M, Roman). toroman(9, ['IX']). toroman(N, ['X'|Roman]) :- N < 40, M is N - 10, toroman(M, Roman). toroman(N, ['XL'|Roman]) :- N < 50, M is N - 40, toroman(M, Roman). toroman(N, ['L'|Roman]) :- N < 90, M is N - 50, toroman(M, Roman). toroman(N, ['XC'|Roman]) :- N < 100, M is N - 90, toroman(M, Roman). toroman(N, ['C'|Roman]) :- N < 400, M is N - 100, toroman(M, Roman). toroman(N, ['CD'|Roman]) :- N < 500, M is N - 400, toroman(M, Roman). toroman(N, ['DD'|Roman]) :- N < 900, M is N - 500, toroman(M, Roman). toroman(N, ['CM'|Roman]) :- N < 1000, M is N - 900, toroman(M, Roman). toroman(N, ['M'|Roman]) :- N < 4000, M is N - 1000, toroman(M, Roman). roman(N, R) :- toroman(N, L), atomic_list_concat(L, R). roman(N) :- roman(N, R), write(R). 

Then you can simply call roman(N, R) and check if R will be combined with the Roman numeral you are interested in.

+1
source

All Articles