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
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]
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