Skip to content

Commit d5544ce

Browse files
committed
elevators
1 parent ad9569e commit d5544ce

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed

challenges/elevators/elevator.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
class Elevator {
2+
constructor(ding) {
3+
this.ding = ding;
4+
this.floor = 0;
5+
this.calls = [];
6+
this.thenWhat();
7+
}
8+
queues(floor) {
9+
this.calls.push(floor);
10+
this.thenWhat();
11+
}
12+
thenWhat() {
13+
if (this.calls.length === 0) {
14+
this.direction = 'waiting';
15+
return;
16+
}
17+
if (this.direction === 'up' && this.ups().length === 0) {
18+
this.direction = 'waiting';
19+
}
20+
if (this.direction === 'down' && this.downs().length === 0) {
21+
this.direction = 'waiting';
22+
}
23+
if (this.direction === 'waiting') {
24+
this.direction = this.calls[0] > this.floor ? 'up' : 'down';
25+
}
26+
}
27+
ups() {
28+
return this.calls.filter((c) => c > this.floor);
29+
}
30+
downs() {
31+
return this.calls.filter((c) => c < this.floor);
32+
}
33+
move() {
34+
this.called = (
35+
this.direction === 'up' ? this.ups() : this.downs()
36+
).sort();
37+
this.floor = this.called[0];
38+
if (this.ding) {
39+
this.ding(this.floor);
40+
}
41+
this.calls.splice(this.calls.indexOf(this.floor), 1);
42+
this.thenWhat();
43+
}
44+
moveAll() {
45+
while (this.calls.length > 0) {
46+
this.move();
47+
}
48+
}
49+
}
50+
51+
module.exports = { Elevator };
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
const { describe, it } = require('node:test');
2+
const { strict: assert } = require('node:assert');
3+
4+
const { Elevator } = require('./elevator');
5+
6+
describe('https://kata-log.rocks/lift-kata', () => {
7+
it('starts from the ground', () => {
8+
const elevator = new Elevator();
9+
10+
assert.deepStrictEqual(elevator.floor, 0);
11+
});
12+
it('starts waiting', () => {
13+
const elevator = new Elevator();
14+
15+
assert.deepStrictEqual(elevator.direction, 'waiting');
16+
});
17+
it('records calls', () => {
18+
const elevator = new Elevator();
19+
elevator.queues(3);
20+
elevator.queues(5);
21+
22+
assert.deepStrictEqual(elevator.calls, [3, 5]);
23+
});
24+
it('knows when the next direction is up', () => {
25+
const elevator = new Elevator();
26+
elevator.queues(3);
27+
elevator.queues(5);
28+
29+
assert.deepStrictEqual(elevator.direction, 'up');
30+
});
31+
it('knows when the next direction is down', () => {
32+
const elevator = new Elevator();
33+
elevator.floor = 5;
34+
elevator.queues(3);
35+
elevator.queues(10);
36+
37+
assert.deepStrictEqual(elevator.direction, 'down');
38+
});
39+
it('can move to called floor', () => {
40+
const elevator = new Elevator();
41+
elevator.floor = 3;
42+
elevator.queues(5);
43+
elevator.move();
44+
45+
assert.deepStrictEqual(elevator.floor, 5);
46+
assert.deepStrictEqual(elevator.calls, []);
47+
assert.deepStrictEqual(elevator.direction, 'waiting');
48+
});
49+
it('can visit three floors up in expected order', () => {
50+
const elevator = new Elevator();
51+
elevator.queues(3);
52+
elevator.queues(5);
53+
elevator.queues(4);
54+
elevator.moveAll();
55+
56+
assert.deepStrictEqual(elevator.floor, 5);
57+
assert.deepStrictEqual(elevator.calls, []);
58+
assert.deepStrictEqual(elevator.direction, 'waiting');
59+
});
60+
it('dings', () => {
61+
let dings = [];
62+
const ding = (floor) => dings.push(floor);
63+
const elevator = new Elevator(ding);
64+
elevator.queues(3);
65+
elevator.queues(5);
66+
elevator.moveAll();
67+
68+
assert.deepStrictEqual(dings, [3, 5]);
69+
});
70+
it('can go up and then down', () => {
71+
let dings = [];
72+
const ding = (floor) => dings.push(floor);
73+
const elevator = new Elevator(ding);
74+
elevator.floor = 3;
75+
elevator.queues(5);
76+
elevator.queues(2);
77+
elevator.moveAll();
78+
79+
assert.deepStrictEqual(dings, [5, 2]);
80+
});
81+
it('can go down and then up', () => {
82+
let dings = [];
83+
const ding = (floor) => dings.push(floor);
84+
const elevator = new Elevator(ding);
85+
elevator.floor = 3;
86+
elevator.queues(2);
87+
elevator.queues(5);
88+
elevator.moveAll();
89+
90+
assert.deepStrictEqual(dings, [2, 5]);
91+
});
92+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const { Elevator } = require('./elevator');
2+
3+
class ElevatorOrchestrator {
4+
constructor(n) {
5+
this.elevators = Array.from({ length: n }, () => new Elevator());
6+
}
7+
queues(floor) {
8+
const freeElevator = this.elevators.find((e) => e.calls.length === 0);
9+
freeElevator.queues(floor);
10+
}
11+
}
12+
13+
module.exports = { ElevatorOrchestrator };
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { describe, it } = require('node:test');
2+
const { strict: assert } = require('node:assert');
3+
4+
const { ElevatorOrchestrator } = require('./orchestrator');
5+
6+
describe('orchestrator', () => {
7+
it('manages several elevators', () => {
8+
const orchestrator = new ElevatorOrchestrator(3);
9+
assert.deepStrictEqual(orchestrator.elevators.length, 3);
10+
});
11+
it('prefers elevator with empty queue', () => {
12+
const orchestrator = new ElevatorOrchestrator(3);
13+
orchestrator.queues(3);
14+
orchestrator.queues(4);
15+
orchestrator.queues(5);
16+
17+
assert.deepStrictEqual(orchestrator.elevators[0].calls, [3]);
18+
assert.deepStrictEqual(orchestrator.elevators[1].calls, [4]);
19+
assert.deepStrictEqual(orchestrator.elevators[2].calls, [5]);
20+
});
21+
});

0 commit comments

Comments
 (0)