"If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?"
Their notes say something about "and" in numbers British-style, but I have ignored this as I have no idea where the ands would go.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use v6; | |
my %number_names = ( | |
1 => "one", | |
2 => "two", | |
3 => "three", | |
4 => "four", | |
5 => "five", | |
6 => "six", | |
7 => "seven", | |
8 => "eight", | |
9 => "nine", | |
10 => "ten", | |
11 => "eleven", | |
12 => "twelve", | |
13 => "thirteen", | |
14 => "fourteen", | |
15 => "fifteen", | |
16 => "sixteen", | |
17 => "seventeen", | |
18 => "eighteen", | |
19 => "nineteen", | |
20 => "twenty", | |
30 => "thirty", | |
40 => "forty", | |
50 => "fifty", | |
60 => "sixty", | |
70 => "seventy", | |
80 => "eighty", | |
90 => "ninety" | |
); | |
for 1..9 -> $n | |
{ | |
%number_names{$n * 100} = %number_names{$n} ~ " hundred"; | |
} | |
sub NumberName(%number_names, $number) | |
{ | |
given $number | |
{ | |
when 0 { return "zero"; } | |
when 1000 { return "one thousand"; } | |
} | |
my $n = $number; | |
my $name = ""; | |
while ($n > 0) | |
{ | |
$name ~= " " if $name.chars > 0; | |
my $biggest = %number_names.keys.grep({$_ <= $n}).map({+$_}).max; | |
$name ~= %number_names{$biggest}; | |
$n -= $biggest; | |
} | |
return $name; | |
} | |
my $letter = 0; | |
for 1..1000 -> $number | |
{ | |
my $name = NumberName(%number_names, $number); | |
# say "$number => $name"; | |
$name.subst(rx/<alpha>/, { $letter++ }, :g); | |
} | |
say $letter; |
This is a slow, stupid way to solve this problem. (Though I'm reasonably happy with it as an example of Perl 6 programming.) On the other hand, this way of doing it makes it much easier to check for correctness. (Though I discovered I'd misspelled one of the numbers in the process of posting this. Sigh.) This runs in just over 3 minutes on my MBP. I will be very disappointed if I can't get that time below 20 seconds. But that is a matter for a future post.
PS I would really like to use Yuval Kogman's system for cleaning up / speeding up Gist embedding in blog posts. Unfortunately, I can't quite make sense of what he is actually doing. Afraid I have fallen a bit behind the technological curve here...
If using Perl 5, this problem just begs for some
ReplyDeleteCPAN leverage:
use 5.10.0;
use Lingua::EN::Numbers qw/ num2en /;
use List::Util qw/ sum /;
say sum map { y/a-z// } map { num2en( $_ ) } 1..1000;
:-)
Ha! Yes, as always, you can get rather drastic improvements by using CPAN.
ReplyDelete