Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Numbers to words

Status
Not open for further replies.

Giovan86

Vendor
Joined
May 10, 2010
Messages
1
Location
CZ
Please help me :) I have no idea what is prolog about and I need to solve this problem - probably very easy for most of you.

I need to transform numbers to words, but not only digits but also teens and tens up to millions. If you can help me, I would really appreciate it. I need it in different language so I canno´t use phrase.

full_words(0) :- !, write(zero), nl.
full_words(N) :- integer(N), N > 0, full_words1(N), nl.

full_words1(0) :- !.
full_words1(N) :- N > 0,
Q is N // 10, R is N mod 10,
full_words1(Q), numberword(R,RW), hyphen(Q), write(RW).

hyphen(0) :- !.
hyphen(Q) :- Q > 0, write('-').

numberword(0,zero).
numberword(1,one).
numberword(2,two).
numberword(3,three).
numberword(4,four).
numberword(5,five).
numberword(6,six).
numberword(7,seven).
numberword(8,eight).
numberword(9,nine).
 
% we'll work with lists since it is easier, and we'll start
% by solving the problem for numbers below 10, then below 100,
% then below 1000 ... this means 1, 2 and 3 digits ... after
% that, the problems simplifies, because we can reuse the
% code for the last 3 digits, and only put thousands, or
% millions, or billions after it ...

% code that solves the problem for two-digit-numbers

% digits writes for numbers below 10
digit(0).
digit(1) :- write(one).
digit(2) :- write(two).
digit(3) :- write(three).
digit(4) :- write(four).
digit(5) :- write(five).
digit(6) :- write(six).
digit(7) :- write(seven).
digit(8) :- write(eight).
digit(9) :- write(nine).

% below_twenty writes for numbers between 10 and 19
below_twenty(0) :- write(ten).
below_twenty(1) :- write(eleven).
below_twenty(2) :- write(twelve).
below_twenty(3) :- write(thirteen).
below_twenty(4) :- write(fourteen).
below_twenty(5) :- write(fifteen).
below_twenty(6) :- write(sixteen).
below_twenty(7) :- write(seventeen).
below_twenty(8) :- write(eighteen).
below_twenty(9) :- write(nineteen).

% tens writes the prefix for numbers between 20 and 99
tens(2) :- write(twenty).
tens(3) :- write(thirty).
tens(4) :- write(fourty).
tens(5) :- write(fifty).
tens(6) :- write(sixty).
tens(7) :- write(seventy).
tens(8) :- write(eighty).
tens(9) :- write(ninety).

% full_words2 deals with any combination of B and C
% that is only 2 digits
full_words2([B, C]) :-
B = 0, !, digit(C).
full_words2([B, C]) :-
B = 1, !, below_twenty(C).
full_words2([B, 0]) :-
!, tens(B).
full_words2([B, C]) :-
tens(B), write(' '), digit(C).


% next we solve the problem for 3 digits

full_words3([A, B, C]) :-
A = 0, !, full_words2([B, C]).
full_words3([A, 0, 0]) :-
!, digit(A), write(' hundred').
full_words3([A, B, C]) :-
digit(A), write(' hundred '), full_words2([B, C]).


% next we solve the problem for 6 digits
full_words6([A, B, C, D, E, F]) :-
A = 0, B = 0, C = 0, !,
full_words3([D, E, F]).
full_words6([A, B, C, D, E, F]) :-
full_words3([A, B, C]),
write(' thousand '),
full_words3([D, E, F]).

% next we solve the problem for 9 digits
full_words9([A, B, C, D, E, F, G, H, I]) :-
A = 0, B = 0, C = 0, !,
full_words6([D, E, F, G, H, I]).
full_words9([A, B, C, D, E, F, G, H, I]) :-
full_words3([A, B, C]),
write(' million '),
full_words6([D, E, F, G, H, I]).

% All there is left to do now is to transform any number N % in a list of 9 digits (since millions is the last
% frontier) ... if a number cannot be represented with 9
% digits, we should put zeroes in front, to make it 9 digits

full_words(X) :-
transform(X, 9, L),
reverse(L, Digits),
full_words9(Digits).

transform(_, 0, []) :- !.
transform(X, N, L) :-
Q is X // 10,
R is X mod 10,
N1 is N - 1,
transform(Q, N1, L1),
L = [R | L1].

% you call full_words(4213), for example
% if you find bugs (there could easily be) please tell me
% and I will correct them
 
Another way is to use DCG, here is an example in French
Code:
lecture(A) --> millions(A).

% we first work on millions then on thousands
millions(A) --> ecrit_millions(A, B), mille(B).

% ecrit_millions(A,B)
% We extract the number of millions , write it with the 
% predicate unite/1 followed by 'million' then we process
% the rest of the number with the predicate mille/1

% special case for 0
ecrit_millions(A,B) -->
	{
	 0 is A // 1000000, !,
	 B is A mod 1000000
	},
	[].


ecrit_millions(A,B) -->
	{
	 NA is A // 1000000,
	 B is A mod 1000000
	},
	unite(NA), [millions].


% same method for mille/1 as for million/1
mille(A) --> ecrit_mille(A, B), unite(B).

% special case for 0
ecrit_mille(A,B) -->
	{
	 0 is A // 1000, !,
	 B is A mod 1000
	},
	[].

% special case for 1, in French we don't say "one mille"
% but "mille" for 1 XXX.
ecrit_mille(A,B) -->
	{
	 1 is A // 1000, !,
	 B is A mod 1000
	},
	[mille].

ecrit_mille(A,B) -->
	{
	 NA is A // 1000,
	 B is A mod 1000
	},
	unite(NA), [mille].



% For unit/1 
unite(B) --> centaine(B, C),dizaine(C, D), unite_simple(D).

centaine(A, B) -->
	{
	   0 is A // 100,
	   !,
	   B is A mod 100
	},
	[].

centaine(A, B) -->
	{
	   1 is A // 100,
	   !,
	   B is A mod 100
	},
	[cent].

centaine(A, B) -->
	{
	   NA is A // 100,
	   NA > 0, !,
	   B is A mod 100
	},
	unite_simple(NA), [cent].

% numeration in French is not easy !
% special cases for numbers between 10 and 20 and for
% numbers ending with 1
dizaine(0, 0) -->  {!}, [].
dizaine(10, 0) --> {!}, [dix].
dizaine(11, 0) --> {!}, [onze].
dizaine(12, 0) --> {!}, [douze].
dizaine(13, 0) --> {!}, [treize].
dizaine(14, 0) --> {!}, [quatorze].
dizaine(15, 0) --> {!}, [quinze].
dizaine(16, 0) --> {!}, [seize].
dizaine(17, 0) --> {!}, [dix-sept].
dizaine(18, 0) --> {!}, [dix-huit].
dizaine(19, 0) --> {!}, [dix-neuf].

dizaine(21, 0) --> {!}, [vingt-et-un].
dizaine(31, 0) --> {!}, [trente-et-un].
dizaine(41, 0) --> {!}, [quarante-et-un].
dizaine(51, 0) --> {!}, [cinquante-et-un].
dizaine(61, 0) --> {!}, [soixante-et-un].
dizaine(71, 0) --> {!}, [soixante-et-onze].
dizaine(81, 0) --> {!}, [quatre-vingt-un].
dizaine(91, 0) --> {!}, [quatre-vingt-onze].

dizaine(A, B) -->
	{
	  A < 10, !,
	  B is A mod 10
	},
	[].

dizaine(A, B) -->
	{
	  A < 30, !,
	  B is A mod 10
	},
	[vingt].

dizaine(A, B) -->
	{
	  A < 40, !,
	  B is A mod 10
	},
	[trente].

dizaine(A, B) -->
	{
	  A < 50, !,
	  B is A mod 10
	},
	[quarante].

dizaine(A, B) -->
	{
	  A < 60, !,
	  B is A mod 10
	},
	[cinquante].

dizaine(A, B) -->
	{
	  A < 70, !,
	  B is A mod 10
	},
	[soixante].

dizaine(A, B) -->
	{
	  A < 80, !,
	  A1 is A - 60
	},
	[soixante],
	dizaine(A1, B).

dizaine(A, B) -->
	{
	  A < 90, !,
	  B is A mod 10
	},
	[quatre-vingt].

dizaine(A, B) -->
	{
	  A1 is A - 80
	},
	[quatre-vingt],
	dizaine(A1, B).

unite_simple(0) --> {!}, [].
unite_simple(1) --> {!}, [un].
unite_simple(2) --> {!}, [deux].
unite_simple(3) --> {!}, [trois].
unite_simple(4) --> {!}, [quatre].
unite_simple(5) --> {!}, [cinq].
unite_simple(6) --> {!}, [six].
unite_simple(7) --> {!}, [sept].
unite_simple(8) --> {!}, [huit].
unite_simple(9) --> {!}, [neuf].
You call it with
Code:
lecture(N) :-
	lecture(N, X ,[]),
	writeln(X).
I hope there is no bug !
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top