secret
Last active

  • Download Gist
paulbarry.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
require 'time'
 
# Monkeypatching FTW! ;)
module Enumerable
def sum
inject(0){|acc,e| acc + e}
end
def avg
size > 0 ? sum / size : 0
end
end
 
class Time
ONE_DAY = 60 * 60 * 24
# Returns a 3 element array containing
# - the time (self) minus one day
# - the time (self)
# - the time (self) plus one day
def plus_or_minus_one_day
[self - ONE_DAY, self, self + ONE_DAY]
end
# Given an Array of Times, this will returns
# a time representing the average all the times
def self.avg(times)
Time.at(times.map{|t| t.to_i}.avg)
end
# Given an Array of Times, this will return
# the time in the Array that is closest to this Time (self)
def closest(times)
if times.empty? then self else
times.min{|a,b| (self - a).abs <=> (self - b).abs }
end
end
end
 
def average_time_of_day(times_of_day)
Time.avg(times_of_day.inject([]) do |times, time_of_day|
time = Time.parse(time_of_day)
avg = times.empty? ? time : Time.avg(times)
times << avg.closest(time.plus_or_minus_one_day)
end).strftime("%l:%M%p").downcase.strip
end
 
if __FILE__ == $0
puts average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
puts average_time_of_day(["6:41am", "6:51am", "7:01am"])
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.