diff options
Diffstat (limited to 'challenge-014/gustavo-chaves')
| -rw-r--r-- | challenge-014/gustavo-chaves/README | 1 | ||||
| -rw-r--r-- | challenge-014/gustavo-chaves/perl5/README.pod | 103 | ||||
| -rwxr-xr-x | challenge-014/gustavo-chaves/perl5/ch-1-recursive.pl | 36 | ||||
| -rwxr-xr-x | challenge-014/gustavo-chaves/perl5/ch-1.pl | 30 | ||||
| -rwxr-xr-x | challenge-014/gustavo-chaves/perl5/ch-2-all.pl | 40 | ||||
| -rwxr-xr-x | challenge-014/gustavo-chaves/perl5/ch-2.pl | 34 | ||||
| -rwxr-xr-x | challenge-014/gustavo-chaves/perl5/ch-extra.pl | 63 |
7 files changed, 307 insertions, 0 deletions
diff --git a/challenge-014/gustavo-chaves/README b/challenge-014/gustavo-chaves/README new file mode 100644 index 0000000000..a66bbbf8a3 --- /dev/null +++ b/challenge-014/gustavo-chaves/README @@ -0,0 +1 @@ +Solution by Gustavo Chaves diff --git a/challenge-014/gustavo-chaves/perl5/README.pod b/challenge-014/gustavo-chaves/perl5/README.pod new file mode 100644 index 0000000000..b01ac3c1f9 --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/README.pod @@ -0,0 +1,103 @@ +=pod + +=encoding utf8 + +=head1 #1 Van Eck's sequence + +=over 4 + +Write a script to generate Van Eck’s sequence starts with 0. For more +information, please check out wikipedia +L<page|https://en.wikipedia.org/wiki/Van_Eck%27s_sequence>. This challenge was +proposed by team member Andrezgz. + +=back + +I wrote two solutions for this challenge: one recursive and one iterative. + +The recursive solution is a little easier to grasp, I think, because it's a more +direct expression of the sequence's definition. But even using memoization it's +33 times slower than the iterative version. + + $ ./ch-1-recursive.pl 10 + 0 + 0 + 1 + 0 + 2 + 0 + 2 + 2 + 1 + 6 + + $ ./ch-1-iterative.pl 10 + 0 + 0 + 1 + 0 + 2 + 0 + 2 + 2 + 1 + 6 + +=head1 #2 Postal Codes + +=over 4 + +Using only the official postal (2-letter) abbreviations for the 50 U.S. states, +write a script to find the longest English word you can spell? Here is the list +of U.S. states abbreviations as per wikipedia +L<page|https://en.wikipedia.org/wiki/List_of_U.S._state_abbreviations>. This +challenge was proposed by team member Neil Bowers. + +=back + +This was an easy one. More so because I could use te L<Locale:US> module to grok +the US Postal Codes. + +But I was dumbfounded when I ran it and saw the result: + + $ ./ch-2-one.pl + Campinas + +Campinas is the name of the city where I live, in Brazil. But I don't have a +clue what is it doing in an English dictionary! :-) + +After having sent my solutions it downed on me that there could be more than one +"largest" word in the dictionary. So, I implemented a second version which +prints all of them: + + $ ./ch-2-all.pl + Campinas + Concorde + Ganymede + Mandarin + Victoria + calamine + complain + mainland + malarial + mandarin + mascaras + memorial + moorland + +=head1 #extra US Traversal + +Neil Bowers blogged about this challenge saying that the second problem wasn't +exactly the one he proposed. He explained what he actually had in mind in a +L<blog post|http://neilb.org/2019/06/24/additional-challenge-14.html>. + +Basically, he wants to know what is the largest English word that can be made +using only the initials if US states, beginning in any of them and following +only adjacent states. He offered a JSON data structure in a GitHub Gist +containing the ajdacency and initials of the states. + +Using the Linux dictionary in F</usr/share/dict/words> my script tells me that +the word is "fatal": + + $ ./ch-extra.pl + fatal (Florida => Alabama => Tennessee => Arkansas => Louisiana) diff --git a/challenge-014/gustavo-chaves/perl5/ch-1-recursive.pl b/challenge-014/gustavo-chaves/perl5/ch-1-recursive.pl new file mode 100755 index 0000000000..98002f0cad --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/ch-1-recursive.pl @@ -0,0 +1,36 @@ +#!/usr/bin/env perl + +# Write a script to generate Van Eck’s sequence starts with 0. For more +# information, please check out wikipedia page +# (https://en.wikipedia.org/wiki/Van_Eck%27s_sequence). This challenge was +# proposed by team member Andrezgz. + +# This is a recursive implementation. + +use 5.026; +use strict; +use warnings; +use Memoize; + +my $sequence_size = shift or die "Usage: $0 SIZE\n"; + +memoize('van_ecks'); +sub van_ecks { + my ($n) = @_; + + return 0 if $n <= 1; + + my $previous_value = van_ecks($n-1); + + for (my $i=$n-2; $i >= 0; --$i) { + if (van_ecks($i) == $previous_value) { + return ($n-1) - $i; + } + } + + return 0; +} + +for my $i (0 .. $sequence_size-1) { + say van_ecks($i); +} diff --git a/challenge-014/gustavo-chaves/perl5/ch-1.pl b/challenge-014/gustavo-chaves/perl5/ch-1.pl new file mode 100755 index 0000000000..3b24e8a570 --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/ch-1.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl + +# Write a script to generate Van Eck’s sequence starts with 0. For more +# information, please check out wikipedia page +# (https://en.wikipedia.org/wiki/Van_Eck%27s_sequence). This challenge was +# proposed by team member Andrezgz. + +# This is an iterative implementation, which is more than 30x faster than the +# recursive one. + +use 5.026; +use strict; +use warnings; + +my $sequence_size = shift or die "Usage: $0 SIZE\n"; + +my @sequence = (0); + +VALUE: +for my $i (0 .. $sequence_size-2) { + for (my $j=$i-1; $j >= 0; --$j) { + if ($sequence[$j] == $sequence[$i]) { + push @sequence, $i-$j; + next VALUE; + } + } + push @sequence, 0; +} + +say foreach @sequence; diff --git a/challenge-014/gustavo-chaves/perl5/ch-2-all.pl b/challenge-014/gustavo-chaves/perl5/ch-2-all.pl new file mode 100755 index 0000000000..726576f4a3 --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/ch-2-all.pl @@ -0,0 +1,40 @@ +#!/usr/bin/env perl + +# Using only the official postal (2-letter) abbreviations for the 50 +# U.S. states, write a script to find the longest English word you can spell? +# Here is the list of U.S. states abbreviations as per wikipedia page +# (https://en.wikipedia.org/wiki/List_of_U.S._state_abbreviations). This +# challenge was proposed by team member Neil Bowers. + +# This version prints all the largest words. + +use 5.026; +use strict; +use autodie; +use warnings; +use Locale::US; +use List::Util qw(all); + +my @postal_codes = Locale::US->new()->all_state_codes(); +my %postal_codes = map {lc($_) => undef} @postal_codes; + +my $largest_length_so_far = 0; +my @largest_words_so_far; + +open my $dict, '<', '/usr/share/dict/words'; +while (<$dict>) { + chomp; + my $word = $_; + next unless length($word) >= $largest_length_so_far; + next unless (length($word) % 2) == 0; + next unless all {exists $postal_codes{$_}} (lc($word) =~ m/../g); + if (length($word) == $largest_length_so_far) { + push @largest_words_so_far, $word; + } else { + $largest_length_so_far = length($word); + @largest_words_so_far = ($word); + } +} +close $dict; + +say foreach @largest_words_so_far; diff --git a/challenge-014/gustavo-chaves/perl5/ch-2.pl b/challenge-014/gustavo-chaves/perl5/ch-2.pl new file mode 100755 index 0000000000..1ef5e6c00e --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/ch-2.pl @@ -0,0 +1,34 @@ +#!/usr/bin/env perl + +# Using only the official postal (2-letter) abbreviations for the 50 +# U.S. states, write a script to find the longest English word you can spell? +# Here is the list of U.S. states abbreviations as per wikipedia page +# (https://en.wikipedia.org/wiki/List_of_U.S._state_abbreviations). This +# challenge was proposed by team member Neil Bowers. + +# This version prints the first largest word. + +use 5.026; +use strict; +use autodie; +use warnings; +use Locale::US; +use List::Util qw(all); + +my @postal_codes = Locale::US->new()->all_state_codes(); +my %postal_codes = map {lc($_) => undef} @postal_codes; + +my $largest_word_so_far = ''; + +open my $dict, '<', '/usr/share/dict/words'; +while (<$dict>) { + chomp; + my $word = $_; + next unless length($word) > length($largest_word_so_far); + next unless (length($word) % 2) == 0; + next unless all {exists $postal_codes{$_}} (lc($word) =~ m/../g); + $largest_word_so_far = $word; +} +close $dict; + +say $largest_word_so_far; diff --git a/challenge-014/gustavo-chaves/perl5/ch-extra.pl b/challenge-014/gustavo-chaves/perl5/ch-extra.pl new file mode 100755 index 0000000000..c5f21c3e25 --- /dev/null +++ b/challenge-014/gustavo-chaves/perl5/ch-extra.pl @@ -0,0 +1,63 @@ +#!/usr/bin/env perl + +# http://neilb.org/2019/06/24/additional-challenge-14.html + +use 5.026; +use strict; +use autodie; +use warnings; +use LWP::Simple; +use JSON; + +my $usa_state_data_url = 'https://gist.githubusercontent.com/neilb/ee60cd179d5eb17d1cb616cdeeda760f/raw/3d31a508a5277ddb4df3a73fb14715102b452302/usa-state-data.json'; + +my $usa_state_data_json = get($usa_state_data_url) + or die "Could not get $usa_state_data_url"; + +my $usa_state_data = decode_json($usa_state_data_json); + +my @all_states = sort keys %$usa_state_data; + +# Mark all states are non-visited yet. +$_->{visited} = 0 foreach values %$usa_state_data; + +sub is_traversable_via { + my ($word, $adjacents) = @_; + + foreach my $state (@{$usa_state_data}{@$adjacents}) { + next if $state->{visited}; + my $initials = $state->{initials}; + next if $initials ne substr($word, 0, length($initials)); + return ($state) if length($initials) eq length($word); + local $state->{visited} = 1; + if (my @path = is_traversable_via(substr($word, length($initials)), $state->{adjacent})) { + return ($state, @path); + } + } + + return; +} + +my $largest_length_so_far = 0; +my @largest_words_so_far; + +open my $dict, '<', '/usr/share/dict/words'; +while (<$dict>) { + chomp; + my $word = $_; + next unless length($word) >= $largest_length_so_far; + if (my @path = is_traversable_via(lc $word, \@all_states)) { + if (length($word) == $largest_length_so_far) { + push @largest_words_so_far, [$word, \@path]; + } else { + $largest_length_so_far = length($word); + @largest_words_so_far = ([$word, \@path]); + } + } +} +close $dict; + +foreach (@largest_words_so_far) { + my ($word, $path) = @$_; + say $word, ' (', join(' => ', map {$_->{name}} @$path), ')'; +} |
