diff options
| author | boblied <boblied@gmail.com> | 2023-02-01 20:33:20 -0600 |
|---|---|---|
| committer | boblied <boblied@gmail.com> | 2023-02-04 07:07:02 -0600 |
| commit | 245f10960be2d521d2f2daa6a02fbe6c0c3fdf53 (patch) | |
| tree | 68eae0353e6a2940c5cfb94ea3926474cde08174 /challenge-179 | |
| parent | a243ee509e2e8cff20e72b6f9a11be93f135f6f2 (diff) | |
| download | perlweeklychallenge-club-245f10960be2d521d2f2daa6a02fbe6c0c3fdf53.tar.gz perlweeklychallenge-club-245f10960be2d521d2f2daa6a02fbe6c0c3fdf53.tar.bz2 perlweeklychallenge-club-245f10960be2d521d2f2daa6a02fbe6c0c3fdf53.zip | |
Week 179 Task 1
Diffstat (limited to 'challenge-179')
| -rw-r--r-- | challenge-179/bob-lied/perl/ch-1.pl | 239 |
1 files changed, 231 insertions, 8 deletions
diff --git a/challenge-179/bob-lied/perl/ch-1.pl b/challenge-179/bob-lied/perl/ch-1.pl index 2db9c74966..bc62051e23 100644 --- a/challenge-179/bob-lied/perl/ch-1.pl +++ b/challenge-179/bob-lied/perl/ch-1.pl @@ -15,15 +15,20 @@ use v5.36; -my @Ones = qw( zeroth first second third fourth - fifth sixth seventh eighth ninth - tenth eleventh twelfth thirteenth fourteenth - fifteenth sixteenth seventeenth eighteenth nineteenth ); +use builtin qw/ceil floor indexed/; +no warnings 'experimental'; -my %Extra = ( 1 => "first", 2 => "second", 3 => "third", 5 => "fifth" ); +my @Ones = qw( zero one two three four five six seven eight nine); +my @Oneth = qw( zeroth first second third fourth fifth sixth + seventh eighth ninth ); -my @Tens = qw( zero teen twenty thirty forty - fifty sixty seventy eighty ninety ); +my @Teen = qw(ten eleven twelve thirteen fourteen fifteen sixteen + seventeen eighteen nineteen); +my @Teenth = map { "${_}th" } @Teen; +$Teenth[2] = "twelfth"; + +my @Tens = qw( zero ten twenty thirty forty fifty sixty seventy eighty ninety ); +my @Tenthieth = map { (my $th = $_) =~ s/y\z/ie/; "${th}th" } @Tens; my @BigName = qw(none thousand million billion trillion quatrillion quintillion sextillion septillion octillion nonillion decillion ); @@ -35,11 +40,229 @@ my $DoTest = 0; GetOptions("test" => \$DoTest, "verbose" => \$Verbose); exit(!runTest()) if $DoTest; +say asOrdinalString($_) for @ARGV; + + +# Returns pairs of 3-digit values and group names, like [321,million][456,thousand] +sub groupThree($n) +{ + my @group; + my $numGrp = ceil(length($n) / 3); + for ( my $i = 0 ; $i < $numGrp ; $i++ ) + { + unshift @group, [ substr($n, -3*($i+1), 3), $BigName[$i] ]; + } + return \@group; +} + +sub asOrdinalString($n) +{ + my $str; + my $group = groupThree($n); + + # For each group of three, form an ordinal number for the least + # group and a cardinal number with its name for the higher groups. + my @parts = map { + my ($val, $grpName) = $_->@*; + $grpName eq 'none' + ? ordinal($val) + : (cardinal($val) . " $grpName") + } $group->@* ; + + # Handle things like 7_000_444 and 1000 -- don't keep things + # like "zero thousand" or "one thousand zeroth" + if ( @parts > 1 ) + { + @parts = grep !/zero/, @parts; + if ( ($n % 1000 ) == 0 ) + { + # If we have a round number, we've stripped away + # the 'zeroth' string at the end, so we have to + # correct it by adding 'th' back to the end. + $parts[-1] .= "th"; + } + } + + $str = join(' ', @parts); + return $str; +} + +# Create a string for a 3-digit number. +sub cardinal($n) +{ + return "zero" if $n == 0; + my $ones = $n % 10; + my $tens = int($n / 10 ) % 10; + my $hunds = int($n / 100 ) % 10; + + my $str; + if ( $ones != 0 ) + { + $str = ( $tens == 1 ? $Teen[$ones] : $Ones[$ones] ); + } + elsif ( $tens == 1 ) + { + $str = ( $Tens[1] ); + } + if ( $tens > 1 ) + { + $str = ( $ones == 0 ? $Tens[$tens] : "$Tens[$tens]-$str" ); + } + if ( $hunds != 0 ) + { + $str = ( $n %100 == 0 ? "$Ones[$hunds] hundred" : "$Ones[$hunds] hundred $str" ); + } + return $str; +} + +# Create an ordinal string for a three-digit number. +sub ordinal($n) +{ + return "zeroth" if $n == 0 ; + + my $ones = $n % 10; + my $tens = int($n / 10 ) % 10; + my $hunds = int($n / 100 ) % 10; + + my $str; + + if ( $ones != 0 ) + { + $str = ( $tens == 1 ? $Teenth[$ones] : $Oneth[$ones] ); + } + elsif ( $tens == 1 ) + { + $str = $Tenthieth[$tens]; + } + if ( $tens > 1 ) + { + $str = ( $ones == 0 ? $Tenthieth[$tens] : "$Tens[$tens]-$str" ); + } + if ( $hunds != 0 ) + { + $str = ( $n %100 == 0 ? "$Ones[$hunds] hundredth" : "$Ones[$hunds] hundred $str" ); + } + return $str; +} + sub runTest { use Test2::V0; - is(0, 1, "FAIL"); + is( groupThree(1), [ [ 1, "none"] ], "Grouping 1"); + is( groupThree(321), [ [321, "none"] ], "Grouping 321"); + is( groupThree(4321), [ [ 4, "thousand"],[321,'none'] ], "Grouping 4321"); + is( groupThree(7654321), [ [7,'million'],[654, "thousand"],[321,'none'] ], "Grouping 7654321"); + is( groupThree(1987654321),[ [ 1,'billion'], + [987,'million'], + [654, "thousand"], + [321,'none'] ], "Grouping 1987654321"); + is( groupThree(4001987654321),[ [ 4,'trillion'], + ['001','billion'], + [987,'million'], + [654, "thousand"], + [321,'none'] ], "Grouping 4001987654321"); + + + is( ordinal( 0), "zeroth", "ord 0"); + is( ordinal( 1), "first", "ord 1"); + is( ordinal( 2), "second", "ord 2"); + is( ordinal( 3), "third", "ord 3"); + is( ordinal( 4), "fourth", "ord 4"); + is( ordinal( 5), "fifth", "ord 5"); + is( ordinal(10), "tenth", "ord 10"); + is( ordinal(11), "eleventh", "ord 11"); + is( ordinal(12), "twelfth", "ord 12"); + is( ordinal(20), "twentieth", "ord 20"); + is( ordinal(30), "thirtieth", "ord 30"); + is( ordinal(40), "fortieth", "ord 40"); + is( ordinal(50), "fiftieth", "ord 50"); + is( ordinal(60), "sixtieth", "ord 60"); + is( ordinal(62), "sixty-second", "ord 62"); + is( ordinal(70), "seventieth", "ord 70"); + is( ordinal(80), "eightieth", "ord 80"); + is( ordinal(90), "ninetieth", "ord 90"); + is( ordinal(91), "ninety-first", "ord 91"); + is( ordinal(92), "ninety-second", "ord 92"); + is( ordinal(93), "ninety-third", "ord 93"); + is( ordinal(94), "ninety-fourth", "ord 94"); + is( ordinal(95), "ninety-fifth", "ord 95"); + is( ordinal(96), "ninety-sixth", "ord 96"); + is( ordinal(97), "ninety-seventh", "ord 97"); + is( ordinal(98), "ninety-eighth", "ord 98"); + is( ordinal(99), "ninety-ninth", "ord 99"); + is( ordinal(100), "one hundredth", "ord 100"); + is( ordinal(101), "one hundred first", "ord 101"); + is( ordinal(111), "one hundred eleventh", "ord 111"); + is( ordinal(233), "two hundred thirty-third", "ord 233"); + + is( cardinal( 0), "zero", "card 0"); + is( cardinal( 1), "one", "card 1"); + is( cardinal( 2), "two", "card 2"); + is( cardinal( 3), "three", "card 3"); + is( cardinal( 4), "four", "card 4"); + is( cardinal( 5), "five", "card 5"); + is( cardinal(10), "ten", "card 10"); + is( cardinal(11), "eleven", "card 11"); + is( cardinal(12), "twelve", "card 12"); + is( cardinal(20), "twenty", "card 20"); + is( cardinal(30), "thirty", "card 30"); + is( cardinal(40), "forty", "card 40"); + is( cardinal(50), "fifty", "card 50"); + is( cardinal(60), "sixty", "card 60"); + is( cardinal(62), "sixty-two", "card 62"); + is( cardinal(70), "seventy", "card 70"); + is( cardinal(80), "eighty", "card 80"); + is( cardinal(90), "ninety", "card 90"); + is( cardinal(91), "ninety-one", "card 91"); + is( cardinal(92), "ninety-two", "card 92"); + is( cardinal(93), "ninety-three", "card 93"); + is( cardinal(94), "ninety-four", "card 94"); + is( cardinal(95), "ninety-five", "card 95"); + is( cardinal(96), "ninety-six", "card 96"); + is( cardinal(97), "ninety-seven", "card 97"); + is( cardinal(98), "ninety-eight", "card 98"); + is( cardinal(99), "ninety-nine", "card 99"); + is( cardinal(100), "one hundred", "card 100"); + is( cardinal(101), "one hundred one", "card 101"); + is( cardinal(111), "one hundred eleven", "card 111"); + is( cardinal(233), "two hundred thirty-three", "card 233"); + + is( asOrdinalString( 0), "zeroth", "asOrdinalString 0"); + is( asOrdinalString( 1), "first", "asOrdinalString 1"); + is( asOrdinalString( 2), "second", "asOrdinalString 2"); + is( asOrdinalString( 3), "third", "asOrdinalString 3"); + is( asOrdinalString( 4), "fourth", "asOrdinalString 4"); + is( asOrdinalString( 5), "fifth", "asOrdinalString 5"); + is( asOrdinalString(11), "eleventh", "asOrdinalString 11"); + is( asOrdinalString(12), "twelfth", "asOrdinalString 12"); + is( asOrdinalString(20), "twentieth", "asOrdinalString 20"); + is( asOrdinalString(30), "thirtieth", "asOrdinalString 30"); + is( asOrdinalString(40), "fortieth", "asOrdinalString 40"); + is( asOrdinalString(50), "fiftieth", "asOrdinalString 50"); + is( asOrdinalString(60), "sixtieth", "asOrdinalString 60"); + is( asOrdinalString(62), "sixty-second", "asOrdinalString 62"); + is( asOrdinalString(70), "seventieth", "asOrdinalString 70"); + is( asOrdinalString(80), "eightieth", "asOrdinalString 80"); + is( asOrdinalString(90), "ninetieth", "asOrdinalString 90"); + is( asOrdinalString(91), "ninety-first", "asOrdinalString 91"); + is( asOrdinalString(92), "ninety-second", "asOrdinalString 92"); + is( asOrdinalString(93), "ninety-third", "asOrdinalString 93"); + is( asOrdinalString(94), "ninety-fourth", "asOrdinalString 94"); + is( asOrdinalString(95), "ninety-fifth", "asOrdinalString 95"); + is( asOrdinalString(96), "ninety-sixth", "asOrdinalString 96"); + is( asOrdinalString(97), "ninety-seventh", "asOrdinalString 97"); + is( asOrdinalString(98), "ninety-eighth", "asOrdinalString 98"); + is( asOrdinalString(99), "ninety-ninth", "asOrdinalString 99"); + is( asOrdinalString(100), "one hundredth", "asOrdinalString 100"); + is( asOrdinalString(101), "one hundred first", "asOrdinalString 101"); + is( asOrdinalString(111), "one hundred eleventh", "asOrdinalString 111"); + is( asOrdinalString(233), "two hundred thirty-third", "asOrdinalString 233"); + is( asOrdinalString(1002003), "one million two thousand third", "asOrdinalString 1002003"); + is( asOrdinalString(10000), "ten thousandth", "asordinalString 10000"); + is( asOrdinalString(10_164_502_713), + "ten billion one hundred sixty-four million five hundred two thousand seven hundred thirteenth", "asOrdinalString 1002003"); + done_testing; } |
