diff --git a/bench0 b/bench0 new file mode 100644 index 0000000..d5fc493 --- /dev/null +++ b/bench0 @@ -0,0 +1,4 @@ +PASS +BenchmarkAddMinutes-12 30000000 45.7 ns/op +BenchmarkCreateClocks-12 30000000 52.1 ns/op +ok exercism/go/clock 3.043s diff --git a/cases_test.go b/cases_test.go index 287e7fe..a39ceda 100644 --- a/cases_test.go +++ b/cases_test.go @@ -22,6 +22,8 @@ var timeTests = []struct { {1, -40, "00:20"}, // negative minutes {1, -160, "22:20"}, // negative minutes roll over {-25, -160, "20:20"}, // negative hour and minutes both roll over + {-25, -1500, "22:00"}, + {-49, -3000, "21:00"}, } // Test adding and subtracting minutes. diff --git a/clock.go b/clock.go index ec7cb27..4a77f95 100644 --- a/clock.go +++ b/clock.go @@ -4,38 +4,54 @@ import "fmt" const ( testVersion = 3 - minutesPerHour = 60 hoursPerDay = 24 + minutesPerHour = 60 + minutesPerDay = 1440 ) +// A Clock stores a minute value representing a time of day. type Clock struct { - hour int minutes int } -func New(hour, minute int) Clock { - h, m := adjustTime(hour, minute) - return Clock{h, m} -} - +// String returns an hour:minute representation of the Clock. func (c Clock) String() string { - return fmt.Sprintf("%02d:%02d", c.hour, c.minutes) + return fmt.Sprintf("%02d:%02d", c.hour(), c.mins()) } +// Add returns a Clock adjusted by the number of minutes specified. func (c Clock) Add(minutes int) Clock { - min := c.minutes + minutes - c.hour, c.minutes = adjustTime(c.hour, min) + c.minutes = parseTime(0, c.minutes+minutes) return c } -func adjustTime(h, m int) (int, int) { - h = (h + (m / minutesPerHour)) % hoursPerDay - if h < 0 { - h += hoursPerDay - } - m = m % minutesPerHour - if m < 0 { - m += minutesPerHour +// hour computes the hourly portion of the Clock. +func (c Clock) hour() int { + return c.minutes / minutesPerHour +} + +// mins computes the non-hourly remainder of the Clock. +func (c Clock) mins() int { + return c.minutes % minutesPerHour +} + +// New returns a Clock constructed from the given hour and minute values. +func New(hour, minutes int) Clock { + return Clock{parseTime(hour, minutes)} +} + +// parseTime computes the number of minutes that represent the time. +func parseTime(hour, minutes int) int { + // normalize hours that are out of range [0-23] + hour = hour % hoursPerDay + // normalize any out of range values [0-1439] + minutes = minutes % minutesPerDay + // compute the total minutes + total := hour * minutesPerHour + total += minutes + // normalize any negative minute values + if total < 0 { + total += minutesPerDay } - return h, m + return total }