You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
53 lines
1.4 KiB
53 lines
1.4 KiB
import { readFileSync } from 'node:fs'; |
|
|
|
const input = readFileSync('input', 'utf-8'); |
|
|
|
const pairs = input |
|
.split('\n\n') |
|
.map(pair => pair |
|
.split('\n') |
|
.filter(line => line) |
|
.map(line => JSON.parse(line)) |
|
); |
|
|
|
export function compare(left, right) { |
|
const leftIsArray = Array.isArray(left); |
|
const rightIsArray = Array.isArray(right); |
|
const compareArrays = leftIsArray || rightIsArray; |
|
if (leftIsArray && !rightIsArray) { |
|
right = [right]; |
|
} |
|
if (rightIsArray && !leftIsArray) { |
|
left = [left]; |
|
} |
|
|
|
if (compareArrays) { |
|
for (let i = 0; i < Math.max(left.length, right.length); i++) { |
|
if (i >= left.length) return -1; |
|
if (i >= right.length) return 1; |
|
|
|
const result = compare(left[i], right[i]); |
|
if (result !== 0) return result; |
|
} |
|
return 0; |
|
} else { |
|
return (left - right) / Math.abs(left - right || 1); |
|
} |
|
} |
|
|
|
const sumOfIndices = pairs |
|
.map(([left, right], i) => [i + 1, compare(left, right)]) |
|
.filter(([_index, result]) => result === -1) |
|
.reduce((total, [index, _result]) => total + index, 0); |
|
|
|
console.log(`Sum of correctly ordered inices: ${sumOfIndices}`); |
|
|
|
const dividerPackets = [[[2]], [[6]]]; |
|
const allPackets = [...pairs.flat(), ...dividerPackets]; |
|
allPackets.sort(compare); |
|
|
|
const decoderKey = dividerPackets |
|
.map(packet => allPackets.indexOf(packet) + 1) |
|
.reduce((total, index) => total * index); |
|
|
|
console.log(`Decoder key: ${decoderKey}`);
|
|
|