My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
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!


Comments
Leave a comment

There are no comments for this entry yet.

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and C++ (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner