Begin forwarded message:

> From: "Paul M. Lambert" <plambert / plambert.net>
> Date: March 30, 2007 2:10:12 PM CDT
> To: submission / rubyquiz.com
> Subject: Quick solution to #118
>
> Just threw this together, and now I'm out of time>
> It implements (badly) the basic requirement, as well as an optional  
> tolerance (for +/- N seconds).
>
> Naturally, there are no comments.  But it seems to work.  Yeah, not  
> exactly a stellar example.  I have lots left to learn, for sure!  :-)
>
> I look forward to seeing others' solutions!
>
> Paul M. Lambert
>
> #!/opt/local/bin/ruby -w
>
> # ruby quiz #118
>
> $calculated_distance_for_number=Hash.new
>
> class Integer
>   def reversed_digits
>     self.to_s.split('').reverse
>   end
> end
>
> def position(digit)
>   if digit.nil? or digit.to_i == 10
>     return 1,3
>   elsif digit.to_i == 0
>     return 0,3
>   else
>     return ((digit.to_i - 1) % 3), ((digit.to_i - 1) / 3)
>   end
> end
>
> def distance_between_digits(a,b)
>   x1, y1 = position(a)
>   x2, y2 = position(b)
>   x = (x1 - x2).abs
>   y = (y1 - y2).abs
>   return (x*x + y*y)
> end
>
> def distance_for_number(num)
>   num = num.to_i
>   if $calculated_distance_for_number[num]
>     return $calculated_distance_for_number[num]
>   end
>   d = num.to_i.reversed_digits
>   total_distance = 0
>
>   last_digit=nil
>   while d.size > 0
>     next_digit = d.shift
>     total_distance += distance_between_digits(last_digit, next_digit)
>     last_digit = next_digit
>   end
>   $calculated_distance_for_number[num] = total_distance
> end
>
> def all_representations_of(s)
>   representations = Array.new
>   mins = (s.to_i / 60)
>   secs = s.to_i - 60*mins
>   if mins == 0
>     [ secs ]
>   elsif secs > 39
>     [ 100*mins+secs ]
>   else
>     [ 100*mins+secs, 100*(mins-1)+secs+60 ]
>   end
> end
>
> def best_input_for(seconds, tolerance=0)
>   tolerance=tolerance.to_i
>   seconds=seconds.to_i
>   range_min=[seconds-tolerance, 0].max
>   range_max=seconds+tolerance
>   representations = Array.new
>   (range_min .. range_max).each do |s|
>     representations.concat(all_representations_of(s))
>   end
>   representations.sort { |a,b| distance_for_number(a) <=>  
> distance_for_number(b) }[0]
> end
>
> [99, 71, 120, 123].each do |s|
>   puts "#{s}: #{best_input_for(s)}"
> end
>