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')