Box Relatives

Thoughts about puzzles, math, coding, and miscellaneous

Deprecated perl

| 12 Comments

Perl, I’m leaving you.

I changed my GMail status to this today and I thought I would give a few words about why. I wanted to go through my Scrabble word list to find five-letter words in which the 3rd and 4th letters were the same, and which became new words when read backward. At first I modified a stock perl script of mine to do it, and then I wondered how easy it would be in Python. So I took a few minutes and came up with this:

#!/usr/bin/python

fid = open('scrabble.txt','r')
dict = [x.rstrip('\r\n') for x in fid.readlines()]
fid.close()
mywords = [x for x in dict if len(x) == 5 and \
x[2] == x[3] and x[::-1] in dict]
print mywords

(Edited to fix a minor error)

How awesome is that? Look at how short, clean, and readable it is! The only slightly tricky part is the

x[::-1]

bit that reverses the string x. So from now on, all my (new) scripting will be in Python. This includes, by the way, the Roman numeral clue page that’s just gone up. So there’s that, too.

Update: here’s Joon’s perl code to do the same thing.

#!/usr/bin/perl
use strict;

my %dict;
open DICT, "scrabble.txt";
while (<DICT>) { chomp; $dict{$_} = 1; }
close DICT;
for (sort keys %dict) { print "$_\n" if (/^..(.)\1.$/ && $dict{reverse($_)}); }

12 Comments

  1. Would be interested in what the perl looked like.

  2. #!/usr/bin/perl
    use strict;

    my %dict;
    open DICT, “scrabble.txt”;
    while () { chomp; $dict{$_} = 1; }
    close DICT;
    for (sort keys %dict) { print “$_\n” if (/^..(.)\1.$/ && $dict{reverse($_)};) }

  3. hmm, it stripped out my <DICT> in the while loop, which i maybe should have expected.

  4. anyway, i don’t think there’s a huge difference. perl’s “reverse” function is more readable than python’s [::-1], but of course the regexp is less readable than the explicit boolean in your python script.

    i was not wowed by python when i test-drove it a few years ago, but i take perl fairly seriously. i know there’s no hell like attempting to decipher somebody else’s write-only perl code, but i try to keep my own fairly clean.

  5. Thanks for the script, Joon.

    What I like about this Python code: no loops! Just list operations. Plus the readability factor. Plus, it took me like an hour to learn enough Python to do that. To do everything in the Perl code … well, it might take a bit longer.

    Anyway, they’re both great languages. But Python is my new flame.

  6. … on the other hand, I just timed both scripts and the perl is twice as fast.

  7. On time, I would imagine that you could make it faster if you wanted. You are reading in the whole file, when you only want to process some of the observations. can you limit dict to only len==5?

    I’d also think that splitting: mywords = [x for x in dict if len(x) == 5 and \
    x[2] == x[3] and x[::-1] in dict]

    into separate steps would help. Continue reducing the number of strings that you are looking at. The reversal must take a lot of cpu.

    But this is just a guess, I’m not a python expert.

  8. Also, why do I have the lamest avatar ever?

  9. How about a little Scala?


    val words = scala.io.Source.fromFile("/users/acruise/ospd3.txt").getLines.toSet

    for {
    word <- words
    if word.size == 5 && word(2) == word(3) && words.contains(word.reverse)
    } yield word

    Note that the for comprehension could be all one line, but I think it’s nicer this way.

    Also at http://paste.pocoo.org/show/392567/ if my syntax gets mangled.

    • Things to note:

      – Statically typed language, but no type annotations required here

      – Thanks to an implicit conversion, Strings can be treated as collections of characters

      – It might seem wasteful to write a ‘toSet’ method for Iterators, but in fact there’s one and only one implementation of toSet. The Scala collections library is Just A Library, but oh what a library! More here: http://www.scala-lang.org/docu/files/collections-api/collections-impl.html

      – The for comprehension is sugar for:

      words.withFilter(word => word.size == 5 && word(2) == word(3) && words.contains(word.reverse)

  10. Pingback: Anagram Word Ladders | Box Relatives

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.