Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
# Given a series of times, computes the average time for the series, returning the
# calculated average time as a string.
#
# >> 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"
require 'time'
DEGREES_IN_CIRCLE = 360.0
TWENTY_FOUR_HOUR_MINUTES = 24 * 60
DEGREES_PER_MINUTE = DEGREES_IN_CIRCLE / TWENTY_FOUR_HOUR_MINUTES
class Time
# Treats hours and minutes as "one hand" on a analog clock for 1440 minute clockface
def degrees
(self.hour * 60 + self.min) * DEGREES_PER_MINUTE
end
# converts degrees to radians
def radians
self.degrees * Math::PI / 180
end
# computes point on circumference of the imaginary 1440 minute clockface
def point
[Math::sin(self.radians), Math::cos(self.radians)]
end
# given a point on the imaginary 1440 minute clockface, returns time object
# corresponding to that point.
def self.at_point(point)
degrees = Math::atan2(point[0], point[1]) * 180 / Math::PI
hr = (degrees / DEGREES_PER_MINUTE / 60).to_i
m = (degrees / DEGREES_PER_MINUTE).round - hr * 60
parse("#{hr}:#{m}")
end
end
def average_time_of_day(times)
# parse the given time strings into Time objects
real_times = times.map{|m| Time.parse(m)}
# sum up and then take average of the points in the time series
sum_pt = real_times.inject([0, 0]) do |pt, t|
pt[0] += t.point[0]
pt[1] += t.point[1]
pt
end
avg_pt = [sum_pt[0] / times.size, sum_pt[1] / times.size]
# translate the computed average back into time object and print
Time.at_point(avg_pt).strftime("%I:%M%p").downcase
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.