aoc/2020/10/part2.js

70 lines
2.2 KiB
JavaScript
Raw Normal View History

2020-12-10 22:07:29 +00:00
const fs = require('fs');
const data = fs.readFileSync('input.txt', 'utf-8');
const lines = data.split('\n').map(num => parseInt(num)).sort((a,b)=>(a-b));
lines.unshift(0);
lines.push(lines[lines.length-1]+3);
// convert to linked list
let last = {};
let i = 0
do {
let entry = {
value: lines[i],
prev: last
};
last.next = entry;
last = entry;
i++;
} while (i < lines.length)
// find removeable adaptors
let removeableAdaptors = [];
const lastVal = last
last = last.prev
while (last.prev) {
if (last.next.value - last.prev.value <= 3){
removeableAdaptors.push(last)
}
last = last.prev
}
// divide removeable adaptors into groups that don't interfere with one another when removed
// this changes the runtime with the given input from a over a month to less than a millisecond
// however, in a worst case scenareo, where every adaptor is removeable, this would still take trillions of years.
let adaptorGroups = []
function makeGroups(removeableAdaptors) {
for (let i = removeableAdaptors.length-1; i>-1; i--) {
// if the gap between two removeable adaptors > 2 then you know they will not intefere with each other
if (i == 0 || removeableAdaptors[i-1].value - removeableAdaptors[i].value > 2) {
adaptorGroups.push(removeableAdaptors.slice(i))
makeGroups(removeableAdaptors.slice(0, i))
break;
}
}
}
makeGroups(removeableAdaptors)
function findArrangements (removeableAdaptors, s = 0) {
total = 1
// for each adaptor in the group
for (let i = s; i < removeableAdaptors.length; i++){
// if you can remove this adaptor
if (removeableAdaptors[i].next.value-removeableAdaptors[i].prev.value <= 3) {
// remove the adaptor and find arrangements with it gone
removeableAdaptors[i].prev.next = removeableAdaptors[i].next
total += findArrangements (removeableAdaptors, i+1)
// add the adaptor back for following tests
removeableAdaptors[i].prev.next = removeableAdaptors[i]
}
}
return total
}
console.time('time')
// multipy the amount of arrangements in each group to get the total amount of arrangements.
answer = adaptorGroups.reduce((a, g) => {return a*findArrangements(g)},1)
console.timeEnd('time')
console.log(answer)