Created
December 17, 2020 01:18
-
-
Save Friss/27ebd341d30f31b76f8c82647f1da1c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs').promises; | |
(async () => { | |
console.log(`Reading input from ${__dirname}/${process.argv[2]}.txt`); | |
const inputData = await fs.readFile(`${__dirname}/${process.argv[2]}.txt`); | |
const inputs = inputData | |
.toString() | |
.split('\n') | |
.filter((n) => n); | |
const rules = []; | |
const yourTicket = []; | |
const nearbyTickets = []; | |
let foundTicket = false; | |
let foundNearby = false; | |
const rangeRegex = /(?<rangeName>.+): (?<lowerMin>\d+)-(?<lowerMax>\d+) or (?<upperMin>\d+)-(?<upperMax>\d+)/; | |
for (let index = 0; index < inputs.length; index++) { | |
const line = inputs[index]; | |
if (rangeRegex.test(line)) { | |
const { | |
rangeName, | |
lowerMin, | |
lowerMax, | |
upperMin, | |
upperMax, | |
} = rangeRegex.exec(line).groups; | |
rules.push({ | |
rangeName, | |
lowerMax: parseInt(lowerMax, 10), | |
lowerMin: parseInt(lowerMin, 10), | |
upperMax: parseInt(upperMax, 10), | |
upperMin: parseInt(upperMin, 10), | |
index: [], | |
}); | |
continue; | |
} | |
if (!foundTicket && line.includes('your ticket')) { | |
foundTicket = true; | |
} | |
if (foundTicket && line.includes(',')) { | |
foundTicket = false; | |
line.split(',').forEach((l) => yourTicket.push(parseInt(l, 10))); | |
} | |
if (!foundNearby && line.includes('nearby tickets')) { | |
foundNearby = true; | |
} | |
if (foundNearby && line.includes(',')) { | |
nearbyTickets.push(line.split(',').map((l) => parseInt(l, 10))); | |
} | |
} | |
let invalidRange = 0; | |
const invalidTickets = new Set(); | |
nearbyTickets.forEach((nearByTicket, ticketIndex) => { | |
for (let index = 0; index < nearByTicket.length; index++) { | |
const num = nearByTicket[index]; | |
const valid = rules.some((rule) => { | |
return ( | |
(num <= rule.lowerMax && num >= rule.lowerMin) || | |
(num <= rule.upperMax && num >= rule.upperMin) | |
); | |
}); | |
if (!valid) { | |
invalidRange += num; | |
invalidTickets.add(ticketIndex); | |
} | |
} | |
}); | |
const validTickets = nearbyTickets.filter((_, i) => !invalidTickets.has(i)); | |
const allValues = []; | |
yourTicket.forEach((value, index) => { | |
const nums = [value, ...validTickets.map((t) => t[index])]; | |
nums.sort((a, b) => a - b); | |
allValues.push(nums); | |
}); | |
const updatedRules = rules.map((rule) => { | |
for (let index = 0; index < allValues.length; index++) { | |
const ticketNumbers = allValues[index]; | |
const allValid = ticketNumbers.every((num) => { | |
return ( | |
(num <= rule.lowerMax && num >= rule.lowerMin) || | |
(num <= rule.upperMax && num >= rule.upperMin) | |
); | |
}); | |
if (allValid) { | |
rule.index.push(index); | |
} | |
} | |
return rule; | |
}); | |
const savedRules = []; | |
updatedRules | |
.sort((a, b) => a.index.length - b.index.length) | |
.map((r) => { | |
r.index = r.index.filter((i) => !savedRules.includes(i)); | |
savedRules.push(r.index[0]); | |
}); | |
const part2 = updatedRules | |
.filter((rule) => rule.rangeName.startsWith('departure')) | |
.reduce((sum, rule) => { | |
return sum * yourTicket[rule.index[0]]; | |
}, 1); | |
console.log('part1', invalidRange); | |
console.log('---'); | |
console.log('part2', part2); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment