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

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}`);