Kata 6

I took a swipe at implementing Dave Thomas’ Kata 6 which is an assignment dealing with anagrams. The goal is to parse a list of 45000-ish words, finding all the words that are anagrams of other words in the file. Dave claims there are 2,530 sets of anagrams, but I only got 2,506. I’m not sure where the disconnect is, but here’s my solution. I welcome any comments and critiques.

 words = IO.readlines("wordlist.txt")  anagrams = Hash.new([])  words.each do |word|     base = Array.new     word.chomp!.downcase!      word.each_byte do |byte|         base << byte.chr     end      base.sort!      anagrams[base.to_s] |= [word] end  # Find the anagrams by eliminating those with only one word anagrams.reject! {|k, v| v.length == 1}  values = anagrams.values.sort do |a, b|     b.length  a.length end  File.open("anagrams.txt", "w") do |file|     values.each do |line|         file.puts(line.join(", "))     end end  largest = anagrams.keys.max do |a, b|     a.length  b.length end  puts "Total: #{anagrams.length}" # puts "Largest set of anagrams: #{values[0].inspect}" #  print "Longest anagram: #{anagrams[largest].inspect} " #  puts "at #{largest.length} characters each" 

Update: Of course, 10 seconds after uploading the code, I see something I could change. Instead of sorting the anagram hash descending by array length, I could have done the following:

 longest = anagrams.to_a.max do |a, b|     a[1].length  b[1].length end 

This will sort and pull the largest one off. The key is bucket 0 and the interesting array is in bucket 1.

The Food Industry Strikes Back

In an effort to inform and entertain people about the spate of ridiculous lawsuits being filed by lard-asses against McDonald’s and other food makers for “making people fat”, a food industry group is launching a series of ads that mock the lawsuits. This Washington Times article has the details. Here’s a funny snippet:

The parodies start with “According to the latest study,” and continue with absurd claims such as “If you eat a wheelbarrow full of cheese fries each week, the cheese fries are to blame when people call you Big Daddy Largepants.”

Come on, folks! Take responsibility for the size of your ass! I’ve taken responsibility for mine! Join Weight Watchers, go on the Atkins Diet, get in The Zone. Just do something! It’s your fault that you are fat, not the people who make the food!

Letterman Funny

Last night David Letterman‘s Top 10 List was the “Top Ten Things The Iraqi Information Minister Has Admitted Since Being Captured”. My favorite was number 10:

Okay, Iraq didn’t win the war. It was a tie.

I almost sprayed Pepsi from my nose when I read that. It’s just like the Black Knight in Monty Python and the Holy Grail who, after getting both arms and both legs hacked off by Arthur says to him:

All right. We’ll call it a draw.

Hilarious! And not too different from some of the absurdities that the “Information Minister” really said during the war!

I Hate Fade-Outs…

I really hate songs that end by just fading out instead of coming to an end. It always strikes me as a cop out; the composer couldn’t think of a good way to end it, so they just turn down the volume until it’s gone. But come on! What are these guys going to do when/if they ever play to a live audience? It’s very annoying.

I will say that I’ve heard two bluegrass bands, The Dillards and The Del McCoury Band do live fade-outs that were technically amazing (they actually kept playing softer until you could barely hear them), but I still felt like they just couldn’t come up with a good way to actually end the dang song… Maybe it’s just me…

“Free” WiFi

I found two links to this BusinessWire story this morning; one at /. and the other at Boing Boing about the island country of Niue rolling out nationwide “free” wireless networking. Why can’t people understand that nothing from the government is ever free? Anything provided by government was paid for from the money seized from the citizens in taxes. And in most countries that have “progressive” tax policies, the majority of that money was taken from the “wealthy.” So everyone now has “free” wifi because some working stiff had to pony up to the tax man.

Big in Nigeria… Update!

Yesterday I wrote about how I had gotten two emails trying to get me to help get loads of cash out of Nigeria and Senegal. I replied to one of them with a single line: “Blow me.” Believe it or not, I actually got a response from the spammer. He said that he didn’t understand the contents of my email and would I please respond with an explanation. Ah, the mind reels at the possibilities…

Pain and Stupidity

Pain = Broken toe.

Worse Pain = Trying to ride a mountain bike with a broken toe and dismounting quickly to keep from hitting my son, landing squarely on the aforementioned broken toe.

Big in Nigeria… And Senegal

I’ve gotten two 419 Scam emails just this morning. One was from the traditional Nigeria, while the other was from Senegal. The first, the Senegalese one, had some of the worst spelling I’ve ever seen. This asshat tells me he needs me to help launder 25 million dollars. Yeah, right. Here’s a sample (yes, it was in all caps, as most of them are):

                                 STRICTLY CONFIDENCIAL DEAR SIR,  I KNOW THIS MAIL WILL COME TO YOU AS A SUPRISE CONSIDERING THE FACT THAT WE HAVE NOT KNOWN EACH OTHER NEITHER WE HAD ANY FORMAL DISCUSSION BEFORE.         HOWEVER, I GOT YOUR ADDRESS COURTESY OF A BUSINESS JOURNAL OF TRADE TRUST, INCOME  STOCK,PROPERTIES INVESTMENT PROMOTION COUNCIL  THROUGH SOME TOP AFRICAN TRADE/INVESTMENTS DELEGATE TO YOUR COUNTRY AND FUTHER SEARCH THROUGH YOUR COUNTRY WED-SIT FROM THE INTERNET .THOUGH AFTER READING THROUGH YOUR ADVERT AND YOUR COMPANY PROFILE, IT INTERESTED ME MUCH TO CONTACT YOU FOR LONGTERM BUSINESS RELATIONSHIP AND INVESTMENT ASSISTANCE IN YOUR COMPANY.  MY NAME IS  JONNY R GUEI, THE SON OF FORMER MILITRY LEADER AND THE HEAD OF STATE OF REPUBLIC OF COTE D"IVORE  LATE GEN.ROBERT GUEI. MY FATHER ALONGSIDE WITH MY MOTHER AND MOST OF MY FAMILY MEMBERS WERE KILLED BY THE REBELS ON THE  19TH SEPT,2002. DURING A COUP ATTEMPT. THE FULL STORY IS BELOW:  1)http://allafrica.com/stories/200209200598.html  2)http://allafrica.com/stories/200209200001.html  3)http://news.bbc.co.uk/2/hi/africa/2269238.stm  4 http://www.cnn.com/2002/WORLD/africa/09/22/ivorycoast/index.html     AFTER THE TRAGIC INCIDENT I AND MY REMAINING FAMILY MEMBERS RAN TO DAKAR-SENEGAL FOR SAFETY DUE TO THE ONGOING POLITICAL CRISIS. WHEN I WAS GOING THROUGH MY FATHER PRIVATE BOX I DISCOVER THAT LAST YEAR MY LATE  FATHER OF BLESSED MEMORY DEPOSITED THE SUM OF$25,000,000,00 US DOLLARS.(TWENTY FIVE MILLION UNITED STATES DOLLARS) WITH ONE  OF THE BANK  HERE IN DAKAR, SENEGAL. HE DECLARED THAT THE FUND BELONGS TO A FOREIGNER  WHO DID CONTRACT WITH THE GOVERNMENT AS A RESULT OF HIS POST IN THE GOVERNMENT.  

I’ve gotten several of these now where they will say that their husband/father/sugar-daddy was assassinated as part of a failed coup, and they will include links to actual CNN or BBC news stories of actual Nigerians being assassinated, to lend credence to their claims. It’s a nice touch, but of course I wasn’t fooled.

I just found this story about a man who was arrested in Canada for scamming people out of 6 million dollars using this method. It amazes me that people are still falling for this after so many years and so much publicity, but they are. I guess greed can really blind people. The news story has a quote from Mark Simchison, the detective in the case where he says that “I truly feel sorry for the victims. They’ve lost everything. There is no further down to go. They’re in the gutter.” You know what? I don’t feel sorry for them. They were driven by greed and the prospect of a pot full of easy cash. They should have known that what they were doing would be illegal, or at least shady, and dealing with people in that realm is dangerous. I say they got what they deserve.

First Cut At Kata 8

Dave Thomas of the Pragmatic Programmers has started publishing programming problems, calling them Kata. He’s just published Kata 8 this morning and I’ve had a go at a solution. The problem is to take a supplied list of words and go through it finding all the six letter words that are constructed from shorter words in the file. The full problem is to write the program in three different ways: one optimized for human consumption, one optimized for speed, and one that is highly extensible.

Presented below is my first cut at this kata. I think it is fairly readable, at 79 lines, so this probably will count as my “fit for human consumption” version. It’s relatively fast, completing in 11 seconds.

Comments? Critiques?

 #!/usr/local/bin/ruby  start = Time.now  # Arrays for each class of word fourLetters = Array.new threeLetters = Array.new twoLetters = Array.new sixLetters = Array.new  # Loop over the word list, segregating the words #  to their respective array IO.foreach("wordlist.txt") do |line|     line.chomp!.downcase!      case line.length     when 2         twoLetters << line     when 3         threeLetters << line     when 4         fourLetters << line     when 6         sixLetters << line     end end  candidates = Array.new  # Build up all combinations of four letters + two letters #  and store in them as candidates fourLetters.each do |four|     twoLetters.each do |two|         wc = four + two          candidates << wc     end end  # Build up all combinations of three letters + three #  letters and store them as candidates threeLetters.each do |three|     threeLetters.each do |otherThree|         wc = three + otherThree         candidates << wc     end end  # Finally, all combinations of two letters + two letters #  + two letters and store those as candidates twoLetters.each do |firstTwo|     twoLetters.each do |secondTwo|         twoLetters.each do |thirdTwo|             wc = firstTwo + secondTwo + thirdTwo             candidates << wc         end     end end  # Now get rid of dups and sort in place candidates.uniq!.sort! puts "Candidates = #{candidates.length}" #  # And the two arrays together leaving only those words #  that appear in both lists matches = sixLetters & candidates  # Now write the matches to a file File.open("matches.txt", "w") do |file|     matches.each do |word|         file.puts(word)     end end  finish = Time.now  puts "Started at #{start}" puts "Finished at #{finish}" puts "Total time #{finish.to_i - start.to_i}"