RPCFN: Average Arrival Time For A Flight (#2)の見直し

RPCFN: Average Arrival Time For A Flight (#2)

12:00pmの扱いがバグってたのを修正
amとpmが混在したときの扱いがバグってたのを修正
Time.atで時刻を出すようにした

MIN = 60
HOUR = MIN*60

def average_time_of_day(args)
  times = []
  r = /(\d+?):(\d+?)(am|pm)/

  args.each do |e| 
    times << r.match(e).to_a[1..-1]
  end 
  
  mixed = !(times.all?{|h,m,meridiam| meridiam =~ /am/} || times.all?{|h,m,meridiam| meridiam =~ /pm/})

  add = mixed ? HOUR*24 : 0 

  average = times.map do |h,m,meridiam|
    h = "0" if h =~/12/
    (meridiam =~ /am/ ? (h.to_i*HOUR + m.to_i*MIN) +add : ((h.to_i*HOUR+HOUR*12 + m.to_i*MIN)))
  end.inject(0) do |sum,t|
    sum + t 
  end / args.size

  Time.at(average).utc.strftime("%I:%M%p").downcase.sub(/^0/,'')
end


OKぽい

>>  average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
=> "12:01am"
>> average_time_of_day(["6:41am", "6:51am", "7:01am"])
=> "6:51am"
>> average_time_of_day ["12:00am", "12:00pm"]
=> "6:00pm"
>> average_time_of_day ["11:58pm", "12:00pm"]
=> "5:59pm"

一等賞のモロッコの人のコード
http://gist.github.com/205002

$am_pm = false
def average_time_of_day(times)
  Time.at(
    times.map! { |t| if t =~ /(\d+):(\d+)(\w*)/
      military = ($1+$2).to_i
      [if    (1200..1259) === military && $3 == 'am'; 0
       elsif (100..1159)  === military && $3 == 'pm'; $1.to_i+12
       else; $1.to_i
       end, $2.to_i]
    end}.map!.with_index {|t,i| t[0] += 24 if t[0] < times[i-1][0] && i!=0; t}.
    inject(0) {|sum,a| sum + a[0]*3600 + a[1]*60}/times.size
  ).strftime($am_pm ? "%I:%M%p" : "%H:%M").downcase
end
 
# To avoid confusion, a 24-hour clock is used (I don't live in a country
# where am/pm is used, nor in a continent, nor near a continent)
# Still, I used this: http://www.mathsisfun.com/time.html to guide me
# through the conversion. Just change the first constant to true to get an am/pm 
# result
 
# My trick here is to use Time.at not to be bored by reverse parsing, since
# it simply generates the time related to the seconds given since Epoch
# (1/1/70 00:00).
 
# I have chosen to code like if all the times were after the previous one. 
# See line #11 for more informations.

やろうとしてる方向は同じだと思うけど、断然スマートだー