Files
advent-of-code/2023/day19/index.js
2024-12-21 21:19:29 +01:00

75 lines
2.5 KiB
JavaScript

import fs from 'node:fs'
function init(filename) {
const data = fs.readFileSync(filename, { encoding: 'utf-8' }, data => data)
const workflow = new Workflow()
let rules = data.split('\n\n')[0].split('\n')
rules.forEach(rule => {
rule.matchAll(/(.*)\{(.*),(\w+)\}/gm)
.forEach(r => {
r[2].split(',').forEach(condition => {
let target = condition.split(':')[1]
let c = condition.split(':')[0]
let operator = condition.charAt(1)
const [first, second] = c.split(operator)
workflow.rules.push({
name: r[1],
key: first,
operator: operator,
value: second,
target: target,
default: r[3]
})
})
})
})
let flows = data.split('\n\n')[1].split('\n')
flows.forEach(flow => {
let newStr = flow.replace(/([a-zA-Z0-9]+)=([a-zA-Z0-9]+)/gm, "\"$1\": $2")
workflow.flows.push(JSON.parse(newStr))
})
workflow.test()
}
class Workflow {
constructor() {
this.rules = []
this.flows = []
}
isConditionValid(operator, value1, value2) {
let result = false
switch (operator) {
case '<': result = value1 < value2 ? true : false; break
case '>': result = value1 > value2 ? true : false; break;
default: break
}
console.log(`${value1} ${operator} ${value2} ? ${result}`)
return result
}
apply(rulename, flow) {
if (!rulename) { rulename = "in" }
if (rulename === 'A') return Object.values(flow).reduce((cur, next) => cur + next, 0)
if (rulename === 'R') return 0
const rules = this.rules.filter(rule => rule.name === rulename)
let new_rule = rules.reduce((prev, current) => current.default, 0)
rules.every(rule => {
if (this.isConditionValid(rule.operator, flow[rule.key], rule.value)) {
new_rule = rule.target
return false
}
return true
})
console.log(`${rulename}: ${rules.map(rule => rule.target).join(", ")} default: ${rules.map(rule => rule.default)} => ${new_rule}`)
return this.apply(new_rule, flow)
}
test() {
const res = this.flows.reduce((prev, current) => prev + parseInt(this.apply(null, current)), 0)
console.log(res)
}
}
init('input.txt')