-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday09.js
executable file
·93 lines (79 loc) · 2.21 KB
/
day09.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
#!/usr/bin/env node
const fs = require('fs');
function pretty(blocks) {
return blocks.map(b => `${`${b.value}`.repeat(b.count)}${'.'.repeat(b.free)}`).join('');
}
function defragment1(blocks) {
blocks = JSON.parse(JSON.stringify(blocks));
for (let i = 0; i < blocks.length - 1; i++) {
const current = blocks[i];
for (let j = blocks.length - 1; j > i; j--) {
const candidate = blocks[j];
const moved = Math.min(candidate.count, current.free);
if (moved > 0) {
blocks.splice(i + 1, 0, {
value: candidate.value,
count: moved,
free: current.free - moved,
});
current.free = 0;
candidate.count -= moved;
break;
}
}
}
return blocks;
}
function defragment2(blocks) {
blocks = JSON.parse(JSON.stringify(blocks));
for (let j = blocks.length - 1; j >= 0; j--) {
const candidate = blocks[j];
for (let i = 0; i < j; i++) {
const current = blocks[i];
const moved = Math.min(candidate.count, current.free);
if (moved > 0 && moved === candidate.count) {
blocks.splice(i + 1, 0, {
value: candidate.value,
count: moved,
free: current.free - moved,
});
j++; // j is shifting up due to the splice/insert above
current.free = 0;
candidate.count -= moved;
blocks[j].free += moved;
break;
}
}
}
return blocks;
}
function checksum(blocks) {
let sum = 0;
let i = 0;
for (const block of blocks) {
for (let j = 0; j < block.count; j++) {
sum += i * block.value;
i++;
}
i += block.free;
}
return sum;
}
if (process.argv.length <= 2) {
console.log('Usage: day09 <path to input>');
process.exit(1);
}
const rawInput = fs.readFileSync(process.argv[2], { encoding: 'utf-8' }).trim();
const input = [...rawInput].map(c => parseInt(c));
const blocks = [...Array(Math.ceil(input.length / 2))]
.map((_, i) => ({
value: i,
count: input[2 * i],
free: input[2 * i + 1] ?? 0
}));
const blocks1 = defragment1(blocks);
const blocks2 = defragment2(blocks);
const part1 = checksum(blocks1);
console.log(`Part 1: ${part1}`);
const part2 = checksum(blocks2);
console.log(`Part 2: ${part2}`);