aboutsummaryrefslogtreecommitdiff
path: root/challenge-014/gustavo-chaves
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-014/gustavo-chaves')
-rw-r--r--challenge-014/gustavo-chaves/README1
-rw-r--r--challenge-014/gustavo-chaves/perl5/README.pod103
-rwxr-xr-xchallenge-014/gustavo-chaves/perl5/ch-1-recursive.pl36
-rwxr-xr-xchallenge-014/gustavo-chaves/perl5/ch-1.pl30
-rwxr-xr-xchallenge-014/gustavo-chaves/perl5/ch-2-all.pl40
-rwxr-xr-xchallenge-014/gustavo-chaves/perl5/ch-2.pl34
-rwxr-xr-xchallenge-014/gustavo-chaves/perl5/ch-extra.pl63
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), ')';
+}