-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day14.ts
102 lines (90 loc) · 2.95 KB
/
Day14.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
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
import readline from "readline/promises";
import { arrayEquals } from "../util.js";
import Solver from "./Solver.js";
type Column = string[];
type Input = Column[];
export default class Day14 extends Solver<Input, number> {
protected PART_1_TEST_OUTPUT = 136;
protected PART_2_TEST_OUTPUT = 64;
protected async parseInput(
lineInterface: readline.Interface,
): Promise<Input> {
const lines = await this.linesToStrings(lineInterface);
const columns: Column[] = Array.from({ length: lines[0].length }, () => []);
for (const line of lines) {
for (let i = 0; i < line.length; i++) {
columns[i].push(line[i]);
}
}
return columns;
}
protected part1(columns: Input): number {
this.tiltColumns(columns);
return this.totalLoad(columns);
}
protected part2(columns: Input): number {
const sequences: number[][] = [];
let curSequence: number[] = [];
let cycles = 0;
let load = 0;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, no-constant-condition
while (true) {
columns = this.doCycle(columns);
load = this.totalLoad(columns);
curSequence.push(load);
cycles++;
if (sequences.some(s => arrayEquals(s, curSequence))) return load;
// Not gonna lie, Copilot made this and I think it's completely random
// Couldn't figure out how to properly check for repeating sequences (which would probably be even faster), but I got the right answer ¯\_(ツ)_/¯
if (cycles % columns.length === 0) {
sequences.push(curSequence);
curSequence = [];
}
}
}
private doCycle(columns: Column[]): Column[] {
this.tiltColumns(columns);
for (let rot = 0; rot < 3; rot++) {
columns = this.rotateColumns(columns);
this.tiltColumns(columns);
}
columns = this.rotateColumns(columns);
return columns;
}
private tiltColumns(columns: Column[]): void {
columns.forEach(c => this.tiltColumn(c));
}
private tiltColumn(column: Column): void {
for (let i = 0; i < column.length; i++) {
if (column[i] === "O") {
let j = i;
while (j > 0 && column[j - 1] === ".") {
column[j] = ".";
column[j - 1] = "O";
j--;
}
}
}
}
private rotateColumns(columns: Column[]): Column[] {
const rotated: Column[] = Array.from(
{ length: columns[0].length },
() => [],
);
for (const column of columns) {
for (let j = 0; j < column.length; j++) {
rotated[column.length - j - 1].push(column[j]);
}
}
return rotated;
}
private totalLoad(columns: Column[]): number {
return columns.reduce((a, b) => a + this.columnLoad(b), 0);
}
private columnLoad(column: Column): number {
return column.reduce((a, b, i) => {
if (b === "O") return a + column.length - i;
return a;
}, 0);
}
}