Javascript
Short and sweet. Basically just handle all the range overlaps for part 2 and then do basic subtraction to get the answer.
spoiler
const input = require('fs').readFileSync('input-day5.txt', 'utf-8');
/** @typedef {[number, number]} Range */
/** @type {[Range[], number[]]} */
const [freshRanges, availableIngredients] = input.split("\n\n").map(l => l.split("\n")).map((l, i) => (i === 1) ? l.map(v => parseInt(v, 10)) : l.map(v => v.split('-').map(vv => parseInt(vv, 10))));
let freshOnHand = 0;
for (const ingredient of availableIngredients) {
for (const [start, stop] of freshRanges) {
if (ingredient >= start && ingredient <= stop) {
freshOnHand += 1;
break;
}
}
}
console.log(`Part 1 Answer: ${freshOnHand}`);
const sortedRanges = [...freshRanges].sort((a, b) => a[0] - b[0]);
const mergedRanges = [];
let current = sortedRanges[0];
for (let i = 1; i < sortedRanges.length; i++) {
const [nextStart, nextEnd] = sortedRanges[i];
if (nextStart <= current[1] + 1) {
current = [current[0], Math.max(current[1], nextEnd)];
} else {
mergedRanges.push(current);
current = [nextStart, nextEnd];
}
}
mergedRanges.push(current);
const freshIngredientCount = mergedRanges.reduce((acc, [start, stop]) => acc + ((stop + 1) - start), 0)
console.log(`Part 2 Answer: ${freshIngredientCount}`);