122 lines
4.0 KiB
Perl
122 lines
4.0 KiB
Perl
#!/usr/bin/env perl
|
|
|
|
use v5.36.0;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use feature 'signatures';
|
|
|
|
my @numbers_one_to_nine = qw/one two three four five six seven eight nine/;
|
|
my @numbers_one_to_nineteen = (@numbers_one_to_nine, qw/ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen/);
|
|
# This is contains an undef in the decenes index just to hopefully catch some warning if gets wrongfully used.)
|
|
my @decenes = (undef, qw/twenty thirty forty fifty sixty seventy eighty ninety/);
|
|
|
|
main();
|
|
|
|
sub main {
|
|
my $start_of_range = $ARGV[0];
|
|
my $end_of_range = $ARGV[1];
|
|
if (!defined $end_of_range) {
|
|
$end_of_range = 1_000_000;
|
|
}
|
|
if (!defined $start_of_range) {
|
|
$start_of_range = 1;
|
|
}
|
|
for (my $i = $start_of_range; $i <= $end_of_range; $i++) {
|
|
say convert_number_to_words($i)
|
|
}
|
|
}
|
|
|
|
sub convert_number_to_words($number) {
|
|
my $return = generate_number_without_uppercase_and_end_marks($number);
|
|
$return =~ s/(\w)/\U$1/;
|
|
$return .= '.';
|
|
return $return;
|
|
}
|
|
|
|
sub generate_number_without_uppercase_and_end_marks($number) {
|
|
my $return = '';
|
|
if ($number < 1) {
|
|
$return .= 'zero';
|
|
return $return;
|
|
}
|
|
# This is done in this way attempting to split the big problem
|
|
# in many smaller problems.
|
|
append_millions_to_return(\$number, \$return);
|
|
my $there_is_hundred_thousands = append_thousand_hundreds_to_return(\$number, \$return);
|
|
append_decene_thousands_to_return(\$number, \$return, $there_is_hundred_thousands);
|
|
append_hundred_to_return(\$number, \$return);
|
|
append_decene_to_return(\$number, \$return);
|
|
return $return;
|
|
}
|
|
|
|
sub append_decene_to_return($number_ref, $return_ref) {
|
|
my $number = ${$number_ref};
|
|
my $decene = int ($number / 1);
|
|
return if ($decene < 1);
|
|
${$return_ref} .= ' and ' if length ${$return_ref};
|
|
${$return_ref} .= convert_two_chars_number_to_words($decene);
|
|
${$number_ref} = 0;
|
|
}
|
|
|
|
sub append_decene_thousands_to_return($number_ref, $return_ref, $there_is_hundred_thousands) {
|
|
my $number = ${$number_ref};
|
|
my $thousand_decene_unit = int ($number / 1_000);
|
|
# This is needed for numbers such as 1_100_001 that do not have thousand decenes
|
|
# but have thousand hundreds.
|
|
if ($there_is_hundred_thousands && $thousand_decene_unit < 1) {
|
|
${$return_ref} .= ' thousand';
|
|
};
|
|
return if ($thousand_decene_unit < 1);
|
|
${$return_ref} .= ' and ' if length ${$return_ref};
|
|
${$return_ref} .= convert_two_chars_number_to_words($thousand_decene_unit) . ' thousand';
|
|
${$number_ref} = $number % 1_000;
|
|
}
|
|
|
|
sub append_hundred_to_return($number_ref, $return_ref) {
|
|
my $number = ${$number_ref};
|
|
my $hundred = int ($number / 100);
|
|
return if ($hundred < 1);
|
|
${$return_ref} .= ', ' if length ${$return_ref};
|
|
${$return_ref} .= $numbers_one_to_nine[$hundred-1] . ' ' . 'hundred';
|
|
${$number_ref} = $number % 100;
|
|
}
|
|
|
|
sub convert_two_chars_number_to_words($number) {
|
|
my $return = '';
|
|
{
|
|
if ($number < 20) {
|
|
$return .= $numbers_one_to_nineteen[$number-1];
|
|
return $return;
|
|
}
|
|
my $decene = int($number / 10);
|
|
$return .= $decenes[$decene-1];
|
|
my $unit = $number % 10;
|
|
if ($unit < 1) {
|
|
return $return;
|
|
}
|
|
$return .= '-';
|
|
$return .= $numbers_one_to_nine[$unit-1];
|
|
}
|
|
return $return;
|
|
}
|
|
|
|
sub append_thousand_hundreds_to_return($number_ref, $return_ref) {
|
|
my $number = ${$number_ref};
|
|
my $thousand_hundreds_unit = int ($number / 100_000);
|
|
return if ($thousand_hundreds_unit < 1);
|
|
${$return_ref} .= ', ' if length ${$return_ref};
|
|
${$return_ref} .= $numbers_one_to_nine[$thousand_hundreds_unit-1] . ' ' . 'hundred';
|
|
${$number_ref} = $number % 100_000;
|
|
return 1;
|
|
}
|
|
|
|
sub append_millions_to_return($number_ref, $return_ref) {
|
|
my $number = ${$number_ref};
|
|
my $millions_unit = int ($number / 1_000_000);
|
|
return if ($millions_unit < 1);
|
|
${$return_ref} .= $numbers_one_to_nine[$millions_unit-1] . ' ' . 'million';
|
|
${$number_ref} = $number % 1_000_000;
|
|
}
|