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.
66 lines
1.7 KiB
66 lines
1.7 KiB
import { readFileSync } from 'node:fs'; |
|
|
|
const input = readFileSync('input', 'utf-8'); |
|
|
|
function priorityForItem(item) { |
|
const c = item.charCodeAt(0); |
|
return c - (c >= 97 ? 96 : 38) |
|
} |
|
|
|
const rucksacks = input |
|
.split('\n') |
|
.filter(line => { |
|
if (!line) return false; |
|
if (line.length % 2 !== 0) { |
|
throw new Error('Rucksack with unequal compartments'); |
|
} |
|
return true; |
|
}) |
|
.map(line => line.split('')) |
|
.map(rucksack => ([ |
|
// compartment 1 |
|
rucksack.slice(0, rucksack.length / 2), |
|
// compartment 2 |
|
rucksack.slice(rucksack.length / 2) |
|
])); |
|
|
|
const sumOfPriorities = rucksacks |
|
.map(([compartment1, compartment2]) => { |
|
const commonItems = [...new Set( |
|
compartment1.filter(item => compartment2.includes(item)) |
|
)]; |
|
if (commonItems.length !== 1) { |
|
throw new Error('Unexpected number of common items'); |
|
} |
|
return priorityForItem(commonItems[0]); |
|
}) |
|
.reduce((total, priority) => total + priority, 0); |
|
|
|
console.log(`Sum of priorities of common items: ${sumOfPriorities}`); |
|
|
|
const elfRucksackGroups = rucksacks |
|
.reduce((groups, rucksack) => { |
|
let group = groups[groups.length - 1]; |
|
if (group.length >= 3) { |
|
group = []; |
|
groups.push(group); |
|
} |
|
group.push(rucksack); |
|
return groups; |
|
}, [[]]); |
|
|
|
const commonItemsInGroup = elfRucksackGroups |
|
.map(group => group |
|
.reduce((itemsA, itemsB) => { |
|
itemsA = [...new Set(itemsA.flat())]; |
|
itemsB = [...new Set(itemsB.flat())]; |
|
return itemsA.filter(item => itemsB.includes(item)) |
|
}) |
|
) |
|
|
|
const badgePriorities = commonItemsInGroup |
|
.map(items => priorityForItem(items[0])) |
|
.reduce((total, priority) => total + priority, 0) |
|
|
|
console.log(`Sum of badge priorities: ${badgePriorities}`); |
|
|
|
|