Brad Fitzpatrick, founder of Livejournal, has a blog post entitled Naming twins in Python & Perl where he writes
Last night at Beau's party, one of Beau's guests mentioned he's expecting twins shortly, which is why is wife wasn't at the party.
I drunkenly suggested he name his kids two names that were anagrams of each other. I then wandered off downstairs to find such suitable names.
Because I'm supposed to be be working in Python these days, not Perl, I gathered what little Python knowledge I had and wrote out:
#!/usr/bin/python
by_anagram = {}
names_file = open("dist.male.first")
for line in names_file:
# lines in file look like:
# WILLIAM 2.451 14.812 5
# we want just the first field.
name = (line.split())[0]
letters = [letter for letter in name]
letters.sort()
sorted_name = "".join(letters)
if not sorted_name in by_anagram:
by_anagram[sorted_name] = []
by_anagram[sorted_name].append(name)
for sorted_name in by_anagram:
if len(by_anagram[sorted_name]) < 2:
continue
print by_anagram[sorted_name]
Not so happy with it, but it worked, and I printed out the results and brought them up to the guy
You can guess where this is going. Below is my solution in C# 3.0
using System;
using System.Linq;
using System.IO;
namespace Name_agram{
class Program{
static void Main(string[] args){
var names = from line in File.ReadAllLines("dist.male.first.txt")
let name = line.Split(' ')[0]
group name by new string(name.ToCharArray().OrderBy(x=>x).ToArray()) into anagrams
select anagrams;
foreach (var list_of_names in names) {
if (list_of_names.Count() > 1)
Console.WriteLine(String.Join(" ",list_of_names.ToArray()));
}
Console.ReadLine();
}
}
}
There are a ton of solutions in various languages in the comments to Brad's post. Again, it is startling to see how different an idiomatic C# 3.0 solution using LINQ is from the traditional imperative/procedural style of programming.
Now Playing: Rick James - Give It To Me Baby