Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 1x 1x 557x 557x 557x 557x 557x 1x 3x 3x 556x 556x 3x 1x 206x 206x 206x 824x 824x 206x 1x 2x 2x 2x 761x 554x 207x 2x 1x 1326x 1326x 1326x 1845x 1845x 875x 157x 157x 718x 718x 451x 451x 48x 403x 1x 2x 2x 2x 2x 2x 205x 205x 205x 205x 205x 123x 123x 2x 1x | const { readFile } = require('../helpers/file') const parseWorkflow = (str) => { const workflowNameExtractor = new RegExp('(.+?)\\{', 'gm') const workflowName = workflowNameExtractor.exec(str)[1] const rules = str .replace(workflowName, '') .replace('{', '') .replace('}', '') .split(',') const fallback = rules.pop() return { name: workflowName, rules, fallback } } const buildWorkflowMap = (data) => { const workflowMap = new Map() for (const line of data) { const workflow = parseWorkflow(line) workflowMap.set(workflow.name, { rules: workflow.rules, fallback: workflow.fallback, }) } return workflowMap } const parseParts = (str) => { let parts = str.replace('{', '').replace('}', '').split(',') const obj = {} for (const part of parts) { const keyValue = part.split('=') obj[keyValue[0]] = parseInt(keyValue[1]) } return obj } const separateWorkflowParts = (fileContent) => { const dataWorkflow = [] const dataParts = [] for (const line of fileContent) { if (!line.startsWith('{') && line !== '') { dataWorkflow.push(line) } else { if (line !== '') dataParts.push(line) } } return [dataWorkflow, dataParts] } const computeIfPartAccepted = ( workflowMap, rules, fallback, parsedPart, finalResult = null ) => { const { x, m, a, s } = parsedPart while (finalResult === null) { for (const rule of rules) { const [condition, goToStep] = rule.split(':') if (eval(condition)) { if (goToStep === 'A' || goToStep === 'R') { finalResult = goToStep return finalResult } else { rules = workflowMap.get(goToStep).rules return computeIfPartAccepted( workflowMap, workflowMap.get(goToStep).rules, workflowMap.get(goToStep).fallback, parsedPart, finalResult ) } } } Eif (finalResult === null) { if (fallback === 'A' || fallback === 'R') { return fallback } return computeIfPartAccepted( workflowMap, workflowMap.get(fallback).rules, workflowMap.get(fallback).fallback, parsedPart, finalResult ) } } return finalResult } const resolvePuzzle = (fileInput) => { const file = readFile(fileInput) const [dataWorkflow, dataParts] = separateWorkflowParts(file) let sum = 0 // Build workflow map const workflowMap = buildWorkflowMap(dataWorkflow) for (const part of dataParts) { const parsedPart = parseParts(part) const rules = workflowMap.get('in').rules const fallback = workflowMap.get('in').fallback const finalResult = computeIfPartAccepted( workflowMap, rules, fallback, parsedPart ) if (finalResult === 'A') { const { x, m, a, s } = parsedPart sum = sum + x + m + a + s } } return sum } module.exports = { parseWorkflow, parseParts, resolvePuzzle, buildWorkflowMap } |