-
-
Save mwlang/ac4e6b87b03b04e5a037 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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