Last active
November 3, 2015 09:10
-
-
Save paulgroves/83171e4d5bb8aaad7ff1 to your computer and use it in GitHub Desktop.
Calculate angles between clock hands
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
class Clock | |
DEGREES = 360.0 | |
MINUTES = 60.0 | |
HOURS = 12.0 | |
attr_accessor :hour, :minute | |
def initialize(hour:, minute:) | |
validate_inputs!(hour, minute) | |
self.hour = hour >= HOURS ? hour - HOURS : hour | |
self.minute = minute | |
end | |
def angle_between_hands | |
hands = [minute_hand_degrees, hour_hand_degrees] | |
format_result(hands.max - hands.min) | |
end | |
def minute_hand_degrees | |
minute * minute_in_degree | |
end | |
def hour_hand_degrees | |
hour_main + hour_fraction | |
end | |
private | |
def format_result(result) | |
result >= DEGREES ? DEGREES - result : result | |
end | |
def validate_inputs!(hour, minute) | |
raise ArgumentError unless (0..24).include?(hour) | |
raise ArgumentError unless (0..59).include?(minute) | |
end | |
def hour_main | |
minute_in_degree * (hour * (MINUTES / HOURS)) | |
end | |
def hour_fraction | |
minute * (hour_in_degrees / MINUTES) | |
end | |
def minute_in_degree | |
DEGREES / MINUTES | |
end | |
def hour_in_degrees | |
DEGREES / HOURS | |
end | |
end |
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
require_relative './clock.rb' | |
RSpec.describe Clock do | |
context '#angle_between_hands' do | |
it '9:30 should be 105!' do | |
expect(Clock.new(hour: 9, minute: 30).angle_between_hands).to eq 105 | |
end | |
it 'should raise with invalid minute' do | |
expect{ Clock.new(hour: 0, minute: 77) }.to raise_error(ArgumentError) | |
end | |
it 'should raise with invalid hour' do | |
expect{ Clock.new(hour: 25, minute: 0) }.to raise_error(ArgumentError) | |
end | |
let(:one_oclock_result) { [30.0, 24.5, 19.0, 13.5, 8.0, 2.5, 3.0, 8.5, 14.0, 19.5, 25.0, 30.5, 36.0, 41.5, 47.0, 52.5, 58.0, 63.5, 69.0, 74.5, 80.0, 85.5, 91.0, 96.5, 102.0, 107.5, 113.0, 118.5, 124.0, 129.5, 135.0, 140.5, 146.0, 151.5, 157.0, 162.5, 168.0, 173.5, 179.0, 184.5, 190.0, 195.5, 201.0, 206.5, 212.0, 217.5, 223.0, 228.5, 234.0, 239.5, 245.0, 250.5, 256.0, 261.5, 267.0, 272.5, 278.0, 283.5, 289.0, 294.5] } | |
let(:two_oclock_result) { [60.0, 54.5, 49.0, 43.5, 38.0, 32.5, 27.0, 21.5, 16.0, 10.5, 5.0, 0.5, 6.0, 11.5, 17.0, 22.5, 28.0, 33.5, 39.0, 44.5, 50.0, 55.5, 61.0, 66.5, 72.0, 77.5, 83.0, 88.5, 94.0, 99.5, 105.0, 110.5, 116.0, 121.5, 127.0, 132.5, 138.0, 143.5, 149.0, 154.5, 160.0, 165.5, 171.0, 176.5, 182.0, 187.5, 193.0, 198.5, 204.0, 209.5, 215.0, 220.5, 226.0, 231.5, 237.0, 242.5, 248.0, 253.5, 259.0, 264.5] } | |
let(:three_oclock_result) { [90.0, 84.5, 79.0, 73.5, 68.0, 62.5, 57.0, 51.5, 46.0, 40.5, 35.0, 29.5, 24.0, 18.5, 13.0, 7.5, 2.0, 3.5, 9.0, 14.5, 20.0, 25.5, 31.0, 36.5, 42.0, 47.5, 53.0, 58.5, 64.0, 69.5, 75.0, 80.5, 86.0, 91.5, 97.0, 102.5, 108.0, 113.5, 119.0, 124.5, 130.0, 135.5, 141.0, 146.5, 152.0, 157.5, 163.0, 168.5, 174.0, 179.5, 185.0, 190.5, 196.0, 201.5, 207.0, 212.5, 218.0, 223.5, 229.0, 234.5] } | |
let(:four_oclock_result) { [120.0, 114.5, 109.0, 103.5, 98.0, 92.5, 87.0, 81.5, 76.0, 70.5, 65.0, 59.5, 54.0, 48.5, 43.0, 37.5, 32.0, 26.5, 21.0, 15.5, 10.0, 4.5, 1.0, 6.5, 12.0, 17.5, 23.0, 28.5, 34.0, 39.5, 45.0, 50.5, 56.0, 61.5, 67.0, 72.5, 78.0, 83.5, 89.0, 94.5, 100.0, 105.5, 111.0, 116.5, 122.0, 127.5, 133.0, 138.5, 144.0, 149.5, 155.0, 160.5, 166.0, 171.5, 177.0, 182.5, 188.0, 193.5, 199.0, 204.5] } | |
let(:five_oclock_result) { [150.0, 144.5, 139.0, 133.5, 128.0, 122.5, 117.0, 111.5, 106.0, 100.5, 95.0, 89.5, 84.0, 78.5, 73.0, 67.5, 62.0, 56.5, 51.0, 45.5, 40.0, 34.5, 29.0, 23.5, 18.0, 12.5, 7.0, 1.5, 4.0, 9.5, 15.0, 20.5, 26.0, 31.5, 37.0, 42.5, 48.0, 53.5, 59.0, 64.5, 70.0, 75.5, 81.0, 86.5, 92.0, 97.5, 103.0, 108.5, 114.0, 119.5, 125.0, 130.5, 136.0, 141.5, 147.0, 152.5, 158.0, 163.5, 169.0, 174.5] } | |
let(:six_oclock_result) { [180.0, 174.5, 169.0, 163.5, 158.0, 152.5, 147.0, 141.5, 136.0, 130.5, 125.0, 119.5, 114.0, 108.5, 103.0, 97.5, 92.0, 86.5, 81.0, 75.5, 70.0, 64.5, 59.0, 53.5, 48.0, 42.5, 37.0, 31.5, 26.0, 20.5, 15.0, 9.5, 4.0, 1.5, 7.0, 12.5, 18.0, 23.5, 29.0, 34.5, 40.0, 45.5, 51.0, 56.5, 62.0, 67.5, 73.0, 78.5, 84.0, 89.5, 95.0, 100.5, 106.0, 111.5, 117.0, 122.5, 128.0, 133.5, 139.0, 144.5] } | |
let(:seven_oclock_result) { [210.0, 204.5, 199.0, 193.5, 188.0, 182.5, 177.0, 171.5, 166.0, 160.5, 155.0, 149.5, 144.0, 138.5, 133.0, 127.5, 122.0, 116.5, 111.0, 105.5, 100.0, 94.5, 89.0, 83.5, 78.0, 72.5, 67.0, 61.5, 56.0, 50.5, 45.0, 39.5, 34.0, 28.5, 23.0, 17.5, 12.0, 6.5, 1.0, 4.5, 10.0, 15.5, 21.0, 26.5, 32.0, 37.5, 43.0, 48.5, 54.0, 59.5, 65.0, 70.5, 76.0, 81.5, 87.0, 92.5, 98.0, 103.5, 109.0, 114.5] } | |
let(:eight_oclock_result) { [240.0, 234.5, 229.0, 223.5, 218.0, 212.5, 207.0, 201.5, 196.0, 190.5, 185.0, 179.5, 174.0, 168.5, 163.0, 157.5, 152.0, 146.5, 141.0, 135.5, 130.0, 124.5, 119.0, 113.5, 108.0, 102.5, 97.0, 91.5, 86.0, 80.5, 75.0, 69.5, 64.0, 58.5, 53.0, 47.5, 42.0, 36.5, 31.0, 25.5, 20.0, 14.5, 9.0, 3.5, 2.0, 7.5, 13.0, 18.5, 24.0, 29.5, 35.0, 40.5, 46.0, 51.5, 57.0, 62.5, 68.0, 73.5, 79.0, 84.5] } | |
let(:nine_oclock_result) { [270.0, 264.5, 259.0, 253.5, 248.0, 242.5, 237.0, 231.5, 226.0, 220.5, 215.0, 209.5, 204.0, 198.5, 193.0, 187.5, 182.0, 176.5, 171.0, 165.5, 160.0, 154.5, 149.0, 143.5, 138.0, 132.5, 127.0, 121.5, 116.0, 110.5, 105.0, 99.5, 94.0, 88.5, 83.0, 77.5, 72.0, 66.5, 61.0, 55.5, 50.0, 44.5, 39.0, 33.5, 28.0, 22.5, 17.0, 11.5, 6.0, 0.5, 5.0, 10.5, 16.0, 21.5, 27.0, 32.5, 38.0, 43.5, 49.0, 54.5] } | |
let(:ten_oclock_result) { [300.0, 294.5, 289.0, 283.5, 278.0, 272.5, 267.0, 261.5, 256.0, 250.5, 245.0, 239.5, 234.0, 228.5, 223.0, 217.5, 212.0, 206.5, 201.0, 195.5, 190.0, 184.5, 179.0, 173.5, 168.0, 162.5, 157.0, 151.5, 146.0, 140.5, 135.0, 129.5, 124.0, 118.5, 113.0, 107.5, 102.0, 96.5, 91.0, 85.5, 80.0, 74.5, 69.0, 63.5, 58.0, 52.5, 47.0, 41.5, 36.0, 30.5, 25.0, 19.5, 14.0, 8.5, 3.0, 2.5, 8.0, 13.5, 19.0, 24.5] } | |
let(:eleven_oclock_result) { [330.0, 324.5, 319.0, 313.5, 308.0, 302.5, 297.0, 291.5, 286.0, 280.5, 275.0, 269.5, 264.0, 258.5, 253.0, 247.5, 242.0, 236.5, 231.0, 225.5, 220.0, 214.5, 209.0, 203.5, 198.0, 192.5, 187.0, 181.5, 176.0, 170.5, 165.0, 159.5, 154.0, 148.5, 143.0, 137.5, 132.0, 126.5, 121.0, 115.5, 110.0, 104.5, 99.0, 93.5, 88.0, 82.5, 77.0, 71.5, 66.0, 60.5, 55.0, 49.5, 44.0, 38.5, 33.0, 27.5, 22.0, 16.5, 11.0, 5.5] } | |
let(:tweleve_oclock_result) { [0.0, 5.5, 11.0, 16.5, 22.0, 27.5, 33.0, 38.5, 44.0, 49.5, 55.0, 60.5, 66.0, 71.5, 77.0, 82.5, 88.0, 93.5, 99.0, 104.5, 110.0, 115.5, 121.0, 126.5, 132.0, 137.5, 143.0, 148.5, 154.0, 159.5, 165.0, 170.5, 176.0, 181.5, 187.0, 192.5, 198.0, 203.5, 209.0, 214.5, 220.0, 225.5, 231.0, 236.5, 242.0, 247.5, 253.0, 258.5, 264.0, 269.5, 275.0, 280.5, 286.0, 291.5, 297.0, 302.5, 308.0, 313.5, 319.0, 324.5] } | |
it 'calculates values for 1 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 1, minute: i).angle_between_hands } | |
expect(subject).to eq(one_oclock_result) | |
end | |
it 'calculates values for 2 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 2, minute: i).angle_between_hands } | |
expect(subject).to eq(two_oclock_result) | |
end | |
it 'calculates values for 3 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 3, minute: i).angle_between_hands } | |
expect(subject).to eq(three_oclock_result) | |
end | |
it 'calculates values for 4 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 4, minute: i).angle_between_hands } | |
expect(subject).to eq(four_oclock_result) | |
end | |
it 'calculates values for 5 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 5, minute: i).angle_between_hands } | |
expect(subject).to eq(five_oclock_result) | |
end | |
it 'calculates values for 6 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 6, minute: i).angle_between_hands } | |
expect(subject).to eq(six_oclock_result) | |
end | |
it 'calculates values for 7 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 7, minute: i).angle_between_hands } | |
expect(subject).to eq(seven_oclock_result) | |
end | |
it 'calculates values for 8 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 8, minute: i).angle_between_hands } | |
expect(subject).to eq(eight_oclock_result) | |
end | |
it 'calculates values for 9 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 9, minute: i).angle_between_hands } | |
expect(subject).to eq(nine_oclock_result) | |
end | |
it 'calculates values for 10 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 10, minute: i).angle_between_hands } | |
expect(subject).to eq(ten_oclock_result) | |
end | |
it 'calculates values for 11 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 11, minute: i).angle_between_hands } | |
expect(subject).to eq(eleven_oclock_result) | |
end | |
it 'calculates values for 12 o\'clock' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 12, minute: i).angle_between_hands } | |
expect(subject).to eq(tweleve_oclock_result) | |
end | |
it 'calculates values for 13 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 13, minute: i).angle_between_hands } | |
expect(subject).to eq(one_oclock_result) | |
end | |
it 'calculates values for 14 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 14, minute: i).angle_between_hands } | |
expect(subject).to eq(two_oclock_result) | |
end | |
it 'calculates values for 15 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 15, minute: i).angle_between_hands } | |
expect(subject).to eq(three_oclock_result) | |
end | |
it 'calculates values for 16 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 16, minute: i).angle_between_hands } | |
expect(subject).to eq(four_oclock_result) | |
end | |
it 'calculates values for 17 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 17, minute: i).angle_between_hands } | |
expect(subject).to eq(five_oclock_result) | |
end | |
it 'calculates values for 18 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 18, minute: i).angle_between_hands } | |
expect(subject).to eq(six_oclock_result) | |
end | |
it 'calculates values for 19 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 19, minute: i).angle_between_hands } | |
expect(subject).to eq(seven_oclock_result) | |
end | |
it 'calculates values for 20 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 20, minute: i).angle_between_hands } | |
expect(subject).to eq(eight_oclock_result) | |
end | |
it 'calculates values for 21 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 21, minute: i).angle_between_hands } | |
expect(subject).to eq(nine_oclock_result) | |
end | |
it 'calculates values for 22 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 22, minute: i).angle_between_hands } | |
expect(subject).to eq(ten_oclock_result) | |
end | |
it 'calculates values for 23 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 23, minute: i).angle_between_hands } | |
expect(subject).to eq(eleven_oclock_result) | |
end | |
it 'calculates values for 00 hrs' do | |
subject = (0..59).to_a.map{ |i| Clock.new(hour: 00, minute: i).angle_between_hands } | |
expect(subject).to eq(tweleve_oclock_result) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment