-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathThe-Bridge.js
103 lines (86 loc) · 2.59 KB
/
The-Bridge.js
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// https://www.codingame.com/training/hard/the-bridge-episode-2
// M - the amount of motorbikes to control
// V - the minimum amount of motorbikes that must survive
const [M, V] = [+readline(), +readline()];
const roads = Array(4)
.fill()
.map(_ => readline().split``.map(c => c === '.'));
const roadLength = roads[0].length;
const copy = bikes => bikes.map(b => ({ x: b.x, y: b.y, speed: b.speed }));
const findPath = (original, V) => {
const results = [];
const applyMove = (bikes, move) =>
bikes
.map(bike => {
const next = bike.x + bike.speed;
let nextLane = bike.y;
let checked = roads[bike.y].slice(bike.x, next);
if (move === 'UP' || move === 'DOWN') {
if (
(move === 'UP' && bike.y === 0) ||
(move === 'DOWN' && bike.y === 3)
) {
checked = [];
bikes = [];
} else {
nextLane = bike.y + (move === 'UP' ? -1 : 1);
checked.push(...roads[nextLane].slice(bike.x, next));
}
}
if (
(checked.some(x => !x) && move !== 'JUMP') ||
(next < roadLength && !roads[nextLane][next])
) {
return null;
}
[bike.x, bike.y] = [next, nextLane];
return bike;
})
.filter(b => b);
for (let move of ['SPEED', 'WAIT', 'JUMP', 'DOWN', 'UP', 'SLOW']) {
let bikes = copy(original);
if (move === 'SPEED') {
bikes.forEach(b => b.speed++);
} else if (move === 'SLOW') {
bikes.forEach(b => b.speed--);
if (bikes[0].speed === 0) {
bikes = [];
}
}
bikes = applyMove(bikes, move);
bikes.length >= V && results.push({ move: move, bikes: bikes });
}
return results;
};
const backtrack = (bikes, V) => {
const [stack, moves] = [[bikes], []];
while (stack.length) {
bikes = stack[0];
!bikes.next && ((bikes.next = findPath(bikes, V)), (bikes.id = 0));
if (bikes[0].x >= roadLength) {
return moves.reverse();
}
if (bikes.id < bikes.next.length) {
let next = bikes.next[bikes.id++];
stack.unshift(next.bikes);
moves.unshift(next.move);
} else {
stack.shift();
moves.shift();
}
}
return null;
};
let move = null;
// game loop
while (true) {
const [speed, bikes] = [+readline(), []];
for (let i = 0; i < M; i++) {
let [x, y, active] = readline().split` `.map(n => +n);
active && bikes.push({ x, y, speed });
}
for (let expected = bikes.length; !move && expected >= V; expected--) {
move = backtrack(copy(bikes), expected);
}
print(move.shift() || 'WAIT');
}