From: Sharon Phillips Date: 2007-04-06T14:34:49+09:00 Subject: Re: [QUIZ] Micrrowave Numbers (#118) Hi, Here's my solution, finally. Takes wanted time as argument 0 and variation as argument 1 Any suggestion on improving this welcome. Cheers, Dave ------------------------ KEY_WIDTH= 10 KEY_HEIGHT= 10 def get_pos (key) case key.to_s when '1'..'9': row, col= (key-1)/3, (key-1)%3 when '0': row, col= 3,0 when '*': row, col= 3,1 end return row, col end def calc_dist (from_key, to_key) from_row, from_col= get_pos(from_key) to_row, to_col= get_pos(to_key) Math.sqrt((KEY_HEIGHT* (to_row- from_row))**2 + (KEY_WIDTH* (to_col- from_col))**2) end def total_dist (keys) return 0 if keys.size==0 dist= 0 keys.each_with_index do |key, i| dist+= calc_dist(keys[i-1], key) if i>0 end dist end def mins_secs_to_keys(mins, secs) keys= [] keys<< mins unless mins.zero? keys<< secs/ 10 unless mins.zero? and (secs/ 10).zero? keys<< secs% 10 keys<< '*' keys end def time_to_candidates(seconds_wanted) mins= seconds_wanted/ 60 secs= seconds_wanted% 60 candidates= [] candidates<< mins_secs_to_keys(mins, secs) candidates<< mins_secs_to_keys(mins- 1, secs+ 60) if mins.nonzero? and secs<40 candidates end seconds= ARGV[0].to_i || 60 variation= ARGV[1].to_i || 0 combos=[] (seconds- variation).upto(seconds+ variation) do |time| combos+= (time_to_candidates(time).map do|keys| {:keys => keys, :dist => total_dist(keys)} end) end print "Best keypad combination for #{seconds}+/-#{variation} seconds is " puts combos.sort{|a, b| a[:dist] <=> b[:dist]}.first[:keys].join(" ")