TomV / tomv.rb secret
Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

refactored based on challenge feedback (unit test, inject, and strfmtime)

View tomv.rb
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
# Ruby Programming Challenge For Newbies, (#2)
# Author: tomv
# (refactored after close of challenge to incorporate feedback: 1.) use inject and 2.) use Test::Unit
#
# Calculate the average time of day from several times in the format
# [ '12:11am', '11:51pm','11:56pm','12:01am', '12:06am']
# returns the average time in string format
# => '12:01am'
# My approach was to get the average difference between each of the
# times, compared to the first time in the list.
# Then add the average difference in time to the base time to get an average.
# The trick was to figure out how to minimize the differences by moving the day around
# since for the edge cases, the next day (12:01 pm) or the previous day (11:55am)
# might yeild a smaller difference that the same time on the same day.
 
# Would be easy to extend this to get a standard deviation of the time differences, so you could
# Likely arrival is "12:30pm +/- 12 minutes in most cases, or something.
#
# I included a simple set of tests as an additional function: test_average_time_of_day()
# that runs through a few test cases.
# Note that the results for average_time_of_day(['12am', '12pm']) could be either '6pm' or '6am'
 
require 'time'
ONE_DAY = 86400 # day in seconds
 
# To run in irb
# >load 'tomv.rb'
# >average_time_of_day([ '12:11am', '11:51pm','11:56pm','12:01am', '12:06am'])
# => "12:01am"
def average_time_of_day(times)
base_time = Time.parse(times[0]) #take the first time, and use as a 'base' then calculate avg. difference.
sum_of_time_differences = times.inject(0.0) do |sum,t|
given_time = Time.parse(t) # Time.parse assumes current day when parsing
if (base_time.hour > 12) # Alternative time is prev day for am or next day for pm
alternative_time = given_time + ONE_DAY
else
alternative_time = given_time - ONE_DAY
end
diff1 = given_time - base_time
diff2 = alternative_time - base_time
sum + ((diff1.abs < diff2.abs)? diff1 : diff2)
end
average_difference = sum_of_time_differences/times.size
average_time = base_time + average_difference
average_time.strftime('%l:%M%p').downcase.strip
end
 
 
###################################################################################
# TEST CASES
###################################################################################
require 'test/unit'
class ChallengeTest < Test::Unit::TestCase
def test_initial_challenge_example_1
assert_equal("12:01am", average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"]))
end
def test_example_2
assert_equal("6:51am", average_time_of_day(["6:41am", "6:51am", "7:01am"]))
end
 
def test_edge_case_noon_and_midnight
assert_equal("6:00pm", average_time_of_day(['12am','12pm']))
end
 
def test_around_midnight_example
assert_equal("12:01am", average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"]))
end
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.