expeditaet
Version:
Advent of Code Solutions
70 lines (58 loc) • 1.73 kB
text/typescript
import { task } from '@alexaegis/advent-of-code-lib';
import {
CircularLinkedList,
CircularLinkedListNode,
} from '@alexaegis/advent-of-code-lib/linked-list';
import { max, min } from '@alexaegis/advent-of-code-lib/math';
import packageJson from '../package.json';
export const p2 = (input: string): number => {
const circle = [...input].map((s) => Number.parseInt(s, 10));
let high = circle.reduce(max);
const low = circle.reduce(min);
let nextLabel = high + 1;
while (circle.length !== 1_000_000) {
circle.push(nextLabel);
nextLabel++;
}
high = circle.reduce(max);
const ll = new CircularLinkedList<number>(circle);
let cursor = ll.head;
const m = new Map<number, CircularLinkedListNode<number>>();
for (const link of cursor.forward()) {
m.set(link.value, link);
}
for (let i = 0; i < 10_000_000; i++) {
// pick up three cups
const front = cursor.next;
cursor.next = front.next.next.next;
// select destination
let destination: CircularLinkedListNode<number> | undefined;
let val = cursor.value;
let sub = 1;
while (
!destination ||
destination === front ||
destination === front.next ||
destination === front.next.next
) {
destination = m.get(val - sub);
sub++;
if (val - sub < low) {
sub = 0;
val = high;
}
}
// reinsert at destination
const after = destination.next;
destination.next = front;
front.prev = destination;
after.prev = front.next.next.next;
front.next.next.next = after;
// next
cursor = cursor.next;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const cup = m.get(1)!;
return cup.next.value * cup.next.next.value;
};
await task(p2, packageJson.aoc); // 286194102744 ~3717.03ms