132 lines
4.2 KiB
Ada
132 lines
4.2 KiB
Ada
with Ada.Text_IO;
|
|
|
|
procedure Integers_In_English is
|
|
|
|
type Spellable is range -999_999_999_999_999_999..999_999_999_999_999_999;
|
|
function Spell (N : Spellable) return String is
|
|
function Twenty (N : Spellable) return String is
|
|
begin
|
|
case N mod 20 is
|
|
when 0 => return "zero";
|
|
when 1 => return "one";
|
|
when 2 => return "two";
|
|
when 3 => return "three";
|
|
when 4 => return "four";
|
|
when 5 => return "five";
|
|
when 6 => return "six";
|
|
when 7 => return "seven";
|
|
when 8 => return "eight";
|
|
when 9 => return "nine";
|
|
when 10 => return "ten";
|
|
when 11 => return "eleven";
|
|
when 12 => return "twelve";
|
|
when 13 => return "thirteen";
|
|
when 14 => return "fourteen";
|
|
when 15 => return "fifteen";
|
|
when 16 => return "sixteen";
|
|
when 17 => return "seventeen";
|
|
when 18 => return "eighteen";
|
|
when others => return "nineteen";
|
|
end case;
|
|
end Twenty;
|
|
|
|
function Decade (N : Spellable) return String is
|
|
begin
|
|
case N mod 10 is
|
|
when 2 => return "twenty";
|
|
when 3 => return "thirty";
|
|
when 4 => return "forty";
|
|
when 5 => return "fifty";
|
|
when 6 => return "sixty";
|
|
when 7 => return "seventy";
|
|
when 8 => return "eighty";
|
|
when others => return "ninety";
|
|
end case;
|
|
end Decade;
|
|
|
|
function Hundred (N : Spellable) return String is
|
|
begin
|
|
if N < 20 then
|
|
return Twenty (N);
|
|
elsif 0 = N mod 10 then
|
|
return Decade (N / 10 mod 10);
|
|
else
|
|
return Decade (N / 10) & '-' & Twenty (N mod 10);
|
|
end if;
|
|
end Hundred;
|
|
|
|
function Thousand (N : Spellable) return String is
|
|
begin
|
|
if N < 100 then
|
|
return Hundred (N);
|
|
elsif 0 = N mod 100 then
|
|
return Twenty (N / 100) & " hundred";
|
|
else
|
|
return Twenty (N / 100) & " hundred and " & Hundred (N mod 100);
|
|
end if;
|
|
end Thousand;
|
|
|
|
function Triplet
|
|
( N : Spellable;
|
|
Order : Spellable;
|
|
Name : String;
|
|
Rest : not null access function (N : Spellable) return String
|
|
) return String is
|
|
High : Spellable := N / Order;
|
|
Low : Spellable := N mod Order;
|
|
begin
|
|
if High = 0 then
|
|
return Rest (Low);
|
|
elsif Low = 0 then
|
|
return Thousand (High) & ' ' & Name;
|
|
else
|
|
return Thousand (High) & ' ' & Name & ", " & Rest (Low);
|
|
end if;
|
|
end Triplet;
|
|
|
|
function Million (N : Spellable) return String is
|
|
begin
|
|
return Triplet (N, 10**3, "thousand", Thousand'Access);
|
|
end Million;
|
|
|
|
function Milliard (N : Spellable) return String is
|
|
begin
|
|
return Triplet (N, 10**6, "million", Million'Access);
|
|
end Milliard;
|
|
|
|
function Billion (N : Spellable) return String is
|
|
begin
|
|
return Triplet (N, 10**9, "milliard", Milliard'Access);
|
|
end Billion;
|
|
|
|
function Billiard (N : Spellable) return String is
|
|
begin
|
|
return Triplet (N, 10**12, "billion", Billion'Access);
|
|
end Billiard;
|
|
|
|
begin
|
|
if N < 0 then
|
|
return "negative " & Spell(-N);
|
|
else
|
|
return Triplet (N, 10**15, "billiard", Billiard'Access);
|
|
end if;
|
|
end Spell;
|
|
|
|
procedure Spell_And_Print(N: Spellable) is
|
|
Number: constant String := Spellable'Image(N);
|
|
Spaces: constant String(1 .. 20) := (others => ' '); -- 20 * ' '
|
|
begin
|
|
Ada.Text_IO.Put_Line(Spaces(Spaces'First .. Spaces'Last-Number'Length)
|
|
& Number & ' ' & Spell(N));
|
|
end Spell_And_Print;
|
|
|
|
Samples: constant array (Natural range <>) of Spellable
|
|
:= (99, 300, 310, 1_501, 12_609, 512_609, 43_112_609, 77_000_112_609,
|
|
2_000_000_000_100, 999_999_999_999_999_999,
|
|
0, -99, -1501, -77_000_112_609, -123_456_789_987_654_321);
|
|
|
|
begin
|
|
for I in Samples'Range loop
|
|
Spell_And_Print(Samples(I));
|
|
end loop;
|
|
end Integers_In_English;
|