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 IamaSherpa 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
May 10, 2010
1
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