Perl Weekly Challenge 014
This week's challenge problems allowed for the nice use of some classic Perl idioms, especially so if you intentionally avoid the use of any CPAN modules which is what I usually do.
As with the previous weekly challenges the problem statements are short and are included in the first comment of the code. The code blocks shown link to GitHub Gists.
$ perl perl5/ch-1.pl
0 0 1 0 2 0 2 2 1 6 0 5 0 2 6 5 4 0 5 3 0 3 2 9 0 4 9 3 6 14 ...
The OEIS entry for this sequence gives a very useful description which (adjusting for zero based indexing) is We start with a(0) = 0. 0 has not appeared before, so the rule says a(1) = 0. Now 0 HAS occurred before, at a(0), which is 1 term before, so a(2) = 1. 1 has not occurred before, so a(3) = 0. 0 appeared most recently at term a(1), which is 2 terms earlier, so a(4) = 2. 2 has not occurred before, so a(5) = 0. And so on.
The code above implements this. The sequence is initialized with the first two terms and then, in an infinite redo loop, the sequence is checked for the occurrence of previous terms and then the next term added accordingly. All previous indices are found using grep and then sorted with the top (most recent) one returned. In the case in which no index is returned 0 is used. It isn't frequently that I use the ternary operator (line 12) but here it is convenient and I can't think why I'd use anything else!
$ perl perl5/ch-2.pl < /usr/share/dict/words
The logic for Part 2 is heavily borrowed from the code from Challenge 005 Part 2. Here the problem does not need as much math. There is no need for prime factors or the Fundamental Theorem of Arithmetic. Instead we just want to see which word has the biggest product when it's letters are substituted with numbers and multiplied together. In this case we only consider letters in specific chunks of two. Each two letter abbreviation is weighted equally (I just chose a value of 2 but anything greater than 1 would be fine, of course).
Line 61 may seem weird and I will admit it's completely unnecessary. I decided to have all the two letter state abbreviations in upper case even though I only use lower case in the actual logic of the program. I did this for no other reason than that they look better that way to me! This is likely because when actually used by the USPS they are always given in upper case so it looks unusual to see them otherwise. Of course this means that Line 61 is necessary to convert them all the lowercase though. I also remove the upper case versions although that in and of itself is also not required since the upper case versions simply won't ever be used.
Co-incidentally I get to use the ternary operator again in line 77! Here this provides a zero factor to the product which will allow us to flag any words which do not only contain two letter state abbreviations. In the dictionary file it turns out there are 360 words which can be made from only these two letter abbreviations.
In the same way as I did for Challenge 005 I used the system dictionary file to find the longest word which in this case is defined as producing unhealthy milk. Interesting! I had never come across this word before.