Skip to content

Commit a5627fe

Browse files
author
Ryan
committed
clock
1 parent 4638ca2 commit a5627fe

File tree

3 files changed

+292
-0
lines changed

3 files changed

+292
-0
lines changed

clock/README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Clock
2+
3+
Implement a clock that handles times without dates.
4+
5+
Create a clock that is independent of date.
6+
7+
You should be able to add and subtract minutes to it.
8+
9+
Two clocks that represent the same time should be equal to each other.
10+
11+
## Setup
12+
13+
Go through the setup instructions for JavaScript to
14+
install the necessary dependencies:
15+
16+
http://exercism.io/languages/javascript
17+
18+
## Making the Test Suite Pass
19+
20+
Execute the tests with:
21+
22+
jasmine-node .
23+
24+
In many test suites all but the first test have been skipped.
25+
26+
Once you get a test passing, you can unskip the next one by
27+
changing `xit` to `it`.
28+
29+
## Source
30+
31+
Pairing session with Erin Drummond [https://twitter.com/ebdrummond](https://twitter.com/ebdrummond)
32+
33+
## Submitting Incomplete Problems
34+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
35+

clock/clock.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const pipe = (first, ...fns) => (...args) => fns.reduce((acc, fn) => fn(acc), first(...args))
2+
3+
const pad = (x) => x < 10 ? `0${x}` : x
4+
const mod = (val) => (x) => x % val
5+
const abs = (val) => (x) => x < 0 ? val + x : x
6+
7+
const hoursPlusMins = (hours, mins) => hours + Math.floor(mins / 60)
8+
9+
const Clock = class {
10+
constructor(hours, mins = 0) {
11+
this.hours = hours
12+
this.mins = mins
13+
}
14+
15+
static at(...args) {
16+
return new Clock(...args)
17+
}
18+
19+
equals(clock) {
20+
return this.toString() === clock.toString()
21+
}
22+
23+
plus(mins) {
24+
this.mins += mins
25+
return this
26+
}
27+
28+
minus(mins) {
29+
this.mins -= mins
30+
return this
31+
}
32+
33+
toString() {
34+
const hours = pipe(hoursPlusMins, mod(24), abs(24), pad)(this.hours, this.mins)
35+
const mins = pipe(mod(60), abs(60), pad)(this.mins)
36+
return `${hours}:${mins}`
37+
}
38+
}
39+
40+
module.exports = Clock

clock/clock.spec.js

+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
var at = require('./clock').at;
2+
3+
describe('Clock', function () {
4+
5+
describe('Creating a new clock with an initial time', function () {
6+
7+
it('on the hour', function () {
8+
expect(at(8).toString()).toEqual('08:00');
9+
});
10+
11+
it('past the hour', function () {
12+
expect(at(11, 9).toString()).toEqual('11:09');
13+
});
14+
15+
it('midnight is zero hours', function () {
16+
expect(at(24, 0).toString()).toEqual('00:00');
17+
});
18+
19+
it('hour rolls over', function () {
20+
expect(at(25, 0).toString()).toEqual('01:00');
21+
});
22+
23+
it('hour rolls over continuously', function () {
24+
expect(at(100, 0).toString()).toEqual('04:00');
25+
});
26+
27+
it('sixty minutes is next hour', function () {
28+
expect(at(1, 60).toString()).toEqual('02:00');
29+
});
30+
31+
it('minutes roll over', function () {
32+
expect(at(0, 160).toString()).toEqual('02:40');
33+
});
34+
35+
it('minutes roll over continuously', function () {
36+
expect(at(0, 1723).toString()).toEqual('04:43');
37+
});
38+
39+
it('hour and minutes roll over', function () {
40+
expect(at(25, 160).toString()).toEqual('03:40');
41+
});
42+
43+
it('hour and minutes roll over continuously', function () {
44+
expect(at(201, 3001).toString()).toEqual('11:01');
45+
});
46+
47+
it('hour and minutes roll over to exactly midnight', function () {
48+
expect(at(72, 8640).toString()).toEqual('00:00');
49+
});
50+
51+
it('negative hour', function () {
52+
expect(at(-1, 15).toString()).toEqual('23:15');
53+
});
54+
55+
it('negative hour rolls over', function () {
56+
expect(at(-25, 0).toString()).toEqual('23:00');
57+
});
58+
59+
it('negative hour rolls over continuously', function () {
60+
expect(at(-91, 0).toString()).toEqual('05:00');
61+
});
62+
63+
it('negative minutes', function () {
64+
expect(at(1, -40).toString()).toEqual('00:20');
65+
});
66+
67+
it('negative minutes rolls over', function () {
68+
expect(at(1, -160).toString()).toEqual('22:20');
69+
});
70+
71+
it('negative minutes rolls over continuously', function () {
72+
expect(at(1, -4820).toString()).toEqual('16:40');
73+
});
74+
75+
it('negative hour and minutes both roll over', function () {
76+
expect(at(-25, -160).toString()).toEqual('20:20');
77+
});
78+
79+
it('negative hour and minutes both roll over continuously', function () {
80+
expect(at(-121, -5810).toString()).toEqual('22:10');
81+
});
82+
83+
describe('Adding and subtracting minutes', function () {
84+
85+
it('add minutes', function () {
86+
expect(at(10, 0).plus(3).toString()).toEqual('10:03');
87+
});
88+
89+
it('add no minutes', function () {
90+
expect(at(6, 41).plus(0).toString()).toEqual('06:41');
91+
});
92+
93+
it('add to next hour', function () {
94+
expect(at(0, 45).plus(40).toString()).toEqual('01:25');
95+
});
96+
97+
it('add more than one hour', function () {
98+
expect(at(10, 0).plus(61).toString()).toEqual('11:01');
99+
});
100+
101+
it('add more than two hours with carry', function () {
102+
expect(at(0, 45).plus(160).toString()).toEqual('03:25');
103+
});
104+
105+
it('add across midnight', function () {
106+
expect(at(23, 59).plus(2).toString()).toEqual('00:01');
107+
});
108+
109+
it('add more than one day (1500 min = 25 hrs)', function () {
110+
expect(at(5, 32).plus(1500).toString()).toEqual('06:32');
111+
});
112+
113+
it('add more than two days', function () {
114+
expect(at(1, 1).plus(3500).toString()).toEqual('11:21');
115+
});
116+
117+
it('subtract minutes', function () {
118+
expect(at(10, 3).minus(3).toString()).toEqual('10:00');
119+
});
120+
121+
it('subtract to previous hour', function () {
122+
expect(at(10, 3).minus(30).toString()).toEqual('09:33');
123+
});
124+
125+
it('subtract more than an hour', function () {
126+
expect(at(10, 3).minus(70).toString()).toEqual('08:53');
127+
});
128+
129+
it('subtract across midnight', function () {
130+
expect(at(0, 3).minus(4).toString()).toEqual('23:59');
131+
});
132+
133+
it('subtract more than two hours', function () {
134+
expect(at(0, 0).minus(160).toString()).toEqual('21:20');
135+
});
136+
137+
it('subtract more than two hours with borrow', function () {
138+
expect(at(6, 15).minus(160).toString()).toEqual('03:35');
139+
});
140+
141+
it('subtract more than one day (1500 min = 25 hrs)', function () {
142+
expect(at(5, 32).minus(1500).toString()).toEqual('04:32');
143+
});
144+
145+
it('subtract more than two days', function () {
146+
expect(at(2, 20).minus(3000).toString()).toEqual('00:20');
147+
});
148+
149+
});
150+
151+
describe('Construct two separate clocks, set times, test if they are equal', function () {
152+
153+
it('clocks with same time', function () {
154+
expect(at(15, 37).equals(at(15, 37))).toBeTruthy();
155+
});
156+
157+
it('clocks a minute apart', function () {
158+
expect(at(15, 36).equals(at(15, 37))).toBeFalsy();
159+
});
160+
161+
it('clocks an hour apart', function () {
162+
expect(at(14, 37).equals(at(15, 37))).toBeFalsy();
163+
});
164+
165+
it('clocks with hour overflow', function () {
166+
expect(at(10, 37).equals(at(34, 37))).toBeTruthy();
167+
});
168+
169+
it('clocks with hour overflow by several days', function () {
170+
expect(at(3, 11).equals(at(99, 11))).toBeTruthy();
171+
});
172+
173+
it('clocks with negative hour', function () {
174+
expect(at(22, 40).equals(at(-2, 40))).toBeTruthy();
175+
});
176+
177+
it('clocks with negative hour that wraps', function () {
178+
expect(at(17, 3).equals(at(-31, 3))).toBeTruthy();
179+
});
180+
181+
it('clocks with negative hour that wraps multiple times', function () {
182+
expect(at(13, 49).equals(at(-83, 49))).toBeTruthy();
183+
});
184+
185+
it('clocks with minute overflow', function () {
186+
expect(at(0, 1).equals(at(0, 1441))).toBeTruthy();
187+
});
188+
189+
it('clocks with minute overflow by several days', function () {
190+
expect(at(2, 2).equals(at(2, 4322))).toBeTruthy();
191+
});
192+
193+
it('clocks with negative minute', function () {
194+
expect(at(2, 40).equals(at(3, -20))).toBeTruthy();
195+
});
196+
197+
it('clocks with negative minute that wraps', function () {
198+
expect(at(4, 10).equals(at(5, -1490))).toBeTruthy();
199+
});
200+
201+
it('clocks with negative minute that wraps multiple times', function () {
202+
expect(at(6, 15).equals(at(6, -4305))).toBeTruthy();
203+
});
204+
205+
it('clocks with negative hours and minutes', function () {
206+
expect(at(7, 32).equals(at(-12, -268))).toBeTruthy();
207+
});
208+
209+
it('clocks with negative hours and minutes that wrap', function () {
210+
expect(at(18, 7).equals(at(-54, -11513))).toBeTruthy();
211+
});
212+
213+
});
214+
215+
});
216+
217+
});

0 commit comments

Comments
 (0)