-
Notifications
You must be signed in to change notification settings - Fork 0
/
part2.ts
70 lines (62 loc) · 2.66 KB
/
part2.ts
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
import * as fs from 'fs';
const input = fs.readFileSync('input', 'utf8').split('\n');
const seeds = input[0]
.split(': ')[1]
.split(' ')
.map((x) => Number(x))
.reduce((a, x, i) => {
if (i % 2 == 0) a.push([]);
return a[a.length - 1].push(x), a;
}, []);
const maps = input.slice(2).map((x) => x.split(' ').map((y) => Number(y)));
const results = [];
function expand(index, values) {
if (index === maps.length) return [values];
const result = [];
const [destination, source, range] = maps[index];
let nextMapIndex = index + 1;
for (; nextMapIndex < maps.length && maps[nextMapIndex].length === 3; nextMapIndex++);
if (
values[0] < source &&
values[0] + values[1] > source &&
values[0] + values[1] <= source + range
) {
// tail part within a map
const firstTuple = [values[0], source - values[0]];
const lastTuple = [destination, values[1] - source + values[0]];
// console.log('last part of ' + values + ' mapped to ' + lastTuple, destination, source, range, index, nextIndex);
result.push(...expand(nextMapIndex, lastTuple), ...expand(index, firstTuple));
} else if (
values[0] >= source &&
values[0] < source + range &&
values[0] + values[1] > source + range
) {
// front part within a map
const firstTuple = [destination + values[0] - source, source + range - values[0]];
const lastTuple = [source + range, values[0] + values[1] - source - range];
// console.log('first part of ' + values + ' mapped to ' + firstTuple, destination, source, range, index, nextIndex);
result.push(...expand(nextMapIndex, firstTuple), ...expand(index, lastTuple));
} else if (values[0] >= source && values[0] + values[1] <= source + range) {
// whole part within a map
// console.log('first part of ' + values + ' mapped to ' + [destination + values[0] - source, values[1]], destination, source, range, index, nextIndex);
result.push(...expand(nextMapIndex, [destination + values[0] - source, values[1]]));
} else if (values[0] < source && values[0] + values[1] > source + range) {
// whole part cover a map
const firstTuple = [values[0], source - values[0]];
const middleTuple = [destination, range];
const lastTuple = [source + range, values[0] + values[1] - source - range];
// console.log('middle part of ' + values + ' mapped to ' + [destination, range], destination, source, range, index, nextIndex);
result.push(
...expand(index, lastTuple),
...expand(nextMapIndex, middleTuple),
...expand(index, firstTuple),
);
}
if (result.length === 0) result.push(...expand(index + 1, values));
return result;
}
for (const seed of seeds) {
results.push(expand(0, seed));
}
console.log(results);
console.log(Math.min(...results.flat().map((x) => x[0])));