This post originated from an RSS feed registered with Java Buzz
by Joey Gibson.
Original Post: First Cut At Kata 8
Feed Title: Joey Gibson's Blog
Feed URL: http://www.jobkabob.com/index.html
Feed Description: Thoughts, musings, ramblings and rants on Java, Ruby, Python, obscure languages, politics and other exciting topics.
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
endend
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
endend
# 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
endend
# 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
endendend
# 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)
endend
finish = Time.now
puts "Started at #{start}"
puts "Finished at #{finish}"
puts "Total time #{finish.to_i - start.to_i}"