Here’s this past week’s NPR puzzle:
Think of a well-known celebrity who goes by a single name — the last two letters of which are alphabetically separated by only one letter (like A and C, or B and D). Replace this pair of letters with the one that separates them, and you’ll have a common, everyday word. What is it?
It used to be that a puzzle like this was tough to solve with a computer program, because there wasn’t a list of famous names available anywhere. Well, now there is such a list, and it makes solving things like this a snap. You will still need a list of common words to solve this puzzle, but those are available all over. I used the Enable dictionary from the NPL.
A few interesting quirks happened along the way to solving this puzzle. First, it turns out that this particular person isn’t listed in Wikipedia by only his/her first name. So I had to tweak the code a bit to look at all possible first names in my list. This created a bit of a logjam because ROBERT -> ROBES comes up a ton. So the final hacked code to give the answer is below. Not my best work, but not bad for ten minutes.
It’s also a relief to see that the intended answer had a score of 100. YAY FAMOUS PEOPLE LIST
#!/usr/bin/perl -w
use strict;
my $USAGE = "Usage: $0 NAME_FILE WORDLIST_FILE";
my $name_file = $ARGV[0] or die $USAGE;
my $word_list_file = $ARGV[1] or die $USAGE;
my %names;
open FILE1, $name_file or die $!;
while (<FILE1>)
{
chomp;
# Everything uppercase for consistency
my $name = uc $_;
my $score = 100;
# Take out names with spaces
#next if $name =~ / /;
if ($name =~ /^(.*)\t(\d+)$/) {$name = $1;$score = $2;}
$names{$name} = $score;
}
close FILE1;
my %words;
open FILE2, $word_list_file or die $!;
while (<FILE2>)
{
chomp;
$words{uc $_} = 1;
}
close FILE2;
# Go through names to find a match
my %used;
while (my ($name, $score) = each(%names))
{
my $first; my $second;
if ($name =~ /^(.*?) /) {$name = $1;}
if ($name =~ /^(.*)(..)$/)
{
$first = $1;
$second = $2;
}
next unless $second;
#print "$name $first $second\n";
my $num = ord(substr($second,0,1));
if (ord(substr($second,1,1)) == $num + 2)
{
my $let = chr($num + 1);
my $word = $first . $let;
if ($words{$word} && !$used{$name})
{
print "$score\t$name\t$word\n";
$used{$name} = 1;
}
}
}
2 Comments
Leave a reply →