YAGNI,
KISS, and the simplest thing that could possibly work reared their heads again (at least for me) at the April meeting of the UH Code Dojo. Luckily for me, a couple of our members bailed us out of what could have been a disaster - greatly complicating a simple problem. (And my apologies for waiting so long to write this up - with finals and final projects all due these couple of weeks, I've just been super busy, as all you other students know all too well).
We decided on using a recent Ruby Quiz as our problem:
Microwave Numbers. The basic idea is: given a number in seconds, identify the most efficient way to push the buttons (based on distance) to get that number of seconds (the actual problem left some room for fuzziness, but we didn't bother with that). This boils down to calculating the distance between any two numbers on the pad, and determining if the number of seconds is greater than 60 (in which case, there will be 2 options to check). Well, at least thats what we came up with.
You can tell immediately I'm suffering from a bad case of not solving little problems that require some thought like this very often. My thoughts are, "ok, lets build a graph of the pad and write a traversal algorithm that we'll run to see how far apart any two numbers are." Luckily, Gino had thought through the problem and had an easier solution: represent the buttons as points in a plane, and calculate the distance as a function given 2 points. Well, that was easy, wasn't it?
The next problem was figuring out how to map the point to which button it represented. Here again, I was thinking of much more complicated things than I needed to be thinking about. Matt came up with the simple solution here: just store the buttons as a string and use the division and modulus to figure the row and column based on the index in the string. Problem solved. After about 15 minutes of thinking through it, we started programming. My laptop is dead at the moment, so we started using why the lucky stiff's
online Ruby interpreter on the computer that was set up in the room (which, didn't have a ruby interpreter as far as I could tell).
As you can imagine, that was a nightmare. But, Gino came to the rescue again and let us use his laptop. After the meeting, he cleaned up the code and sent it to us, and Matt did some of the programming, so its in camelCase style (and I didn't want to spend the time to rubify it), but it works just fine. Next time, I want to write some unit tests first - as it would have been helpful for verification purposes here, rather than trying to run separate tests by hand each time we made a change. Anyway, with no further ado, here's the code we came up with for you to enjoy:
class Microwave
def initialize
@buttons = "123456789#0*"
end
def getShortestEntry(seconds)
minDistance = 10000;
minPress = "";
opt = 1;
puts "Input:#{seconds}\n---------------"
(0..seconds/60).each do|minute|
remSeconds = seconds - 60 * minute
if remSeconds < 100
buttonPress = timeEntry(minute, remSeconds)
totalDistance = 0
(0..buttonPress.length() - 2).each do |char|
totalDistance += manhattanDistance(buttonPress[char, 1], buttonPress[char + 1, 1])
end
puts "opt#{opt}: #{buttonPress} d=#{totalDistance}"
opt = opt + 1
if totalDistance < minDistance
minDistance = totalDistance
minPress = buttonPress
end
end
end
return minPress
end
def manhattanDistance(from, to)
fromIndex = @buttons.index(from.to_s)
toIndex = @buttons.index(to.to_s)
rowFrom = fromIndex/3
colFrom = fromIndex%3
rowTo = toIndex / 3
colTo = toIndex % 3
return ((rowFrom - rowTo).abs + (colFrom - colTo).abs)
end
def timeEntry(minute, seconds)
str = (minute == 0 ? "" : minute.to_s)
str = str + (seconds < 10 ? "0" : "") + seconds.to_s
return (str + "*")
end
end
mwave = Microwave.new
[33, 61, 99, 101, 71, 120, 123, 222, 737].each do |inSeconds|
puts "The shortest entry for #{inSeconds} seconds: #{mwave.getShortestEntry(inSeconds)}\n "
end
Hey! Why don't you make your life easier and subscribe to the full post
or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate
wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!
Leave a comment
There are no comments for this entry yet.
Leave a comment