-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2dfde02
commit 5f10561
Showing
3 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
module.exports = input => { | ||
let [workflows, parts] = input.split(/\r?\n\r?\n/) | ||
.map(g => g.split(/\r?\n/)); | ||
|
||
workflows = workflows.map(w => w.match(/(\w+)\{(.*)\}/)) | ||
.map(([_, id, w]) => [id, w.split(',')]) | ||
.reduce((map, [id, w]) => map.set(id, w), new Map()); | ||
|
||
const eval = (id, values) => { | ||
if (id == 'A') { | ||
return true; | ||
} | ||
if (id == 'R') { | ||
return false; | ||
} | ||
|
||
let rules = workflows.get(id); | ||
for (let rule of rules) { | ||
if (rule.indexOf(':') >= 0) { | ||
let [condition, result] = rule.split(':'); | ||
let [_, rating, comparison, value] = condition.match(/(\w)([<>])(\d+)/); | ||
let testee = values['xmas'.indexOf(rating)]; | ||
value = Number(value); | ||
if ((comparison == '>' && testee > value) | ||
|| (comparison == '<' && testee < value)) { | ||
return eval(result, values); | ||
} | ||
} else { | ||
return eval(rule, values); | ||
} | ||
} | ||
} | ||
|
||
parts = parts.map(p => p.slice(1, p.length - 1)) | ||
.map(p => p.split(',').map(r => Number(r.split('=')[1]))); | ||
|
||
return parts.filter(p => eval('in', p)) | ||
.map(([x, m, a, s]) => x + m + a + s) | ||
.reduce((a, b) => a + b); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
function range(r1, r2) { | ||
return r1 > r2 ? [] : [r1, r2]; | ||
} | ||
|
||
function split([r1, r2], comparison, value) { | ||
if (comparison == '>') { | ||
return [range(Math.max(value + 1, r1), r2), range(r1, Math.min(r2, value))]; | ||
} else { | ||
return [range(r1, Math.min(value - 1, r2)), range(Math.max(value, r1), r2)]; | ||
} | ||
} | ||
|
||
module.exports = input => { | ||
let [workflows, _] = input.split(/\r?\n\r?\n/) | ||
.map(g => g.split(/\r?\n/)); | ||
|
||
workflows = workflows.map(w => w.match(/(\w+)\{(.*)\}/)) | ||
.map(([_, id, w]) => [id, w.split(',')]) | ||
.reduce((map, [id, w]) => map.set(id, w), new Map()); | ||
|
||
const eval = (id, ranges) => { | ||
if (id == 'A') { | ||
return [ranges]; | ||
} | ||
if (id == 'R') { | ||
return [[], [], [], []]; | ||
} | ||
|
||
let rules = workflows.get(id); | ||
let results = []; | ||
|
||
for (let rule of rules) { | ||
if (rule.indexOf(':') >= 0) { | ||
let [condition, result] = rule.split(':'); | ||
let [_, rating, comparison, value] = condition.match(/(\w)([<>])(\d+)/); | ||
let index = 'xmas'.indexOf(rating); | ||
let testRange = ranges[index]; | ||
value = Number(value); | ||
|
||
let [positive, negative] = split(testRange, comparison, value); | ||
|
||
if (positive.length) { | ||
let nranges = [...ranges]; | ||
nranges.splice(index, 1, positive); | ||
results.push(...eval(result, nranges)); | ||
} | ||
|
||
if (negative.length == 0) { | ||
break; | ||
} | ||
|
||
ranges = [...ranges]; | ||
ranges.splice(index, 1, negative) | ||
} | ||
else { | ||
results.push(...eval(rule, ranges)); | ||
} | ||
} | ||
|
||
return results.filter(r => r.some(p => p.length)); | ||
} | ||
|
||
return eval('in', [[1, 4000], [1, 4000], [1, 4000], [1, 4000]]) | ||
.map(r => r.reduce((p, [r1, r2]) => p * (r2 - r1 + 1), 1)) | ||
.reduce((a, b) => a + b); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
const expect = require('expect.js'); | ||
const part1 = require('./part1'); | ||
const part2 = require('./part2'); | ||
|
||
describe('Day 19: Part 1', () => { | ||
it('Should sum rating number for all accepted parts', () => { | ||
expect(part1(`px{a<2006:qkq,m>2090:A,rfg} | ||
pv{a>1716:R,A} | ||
lnx{m>1548:A,A} | ||
rfg{s<537:gd,x>2440:R,A} | ||
qs{s>3448:A,lnx} | ||
qkq{x<1416:A,crn} | ||
crn{x>2662:A,R} | ||
in{s<1351:px,qqz} | ||
qqz{s>2770:qs,m<1801:hdj,R} | ||
gd{a>3333:R,R} | ||
hdj{m>838:A,pv} | ||
{x=787,m=2655,a=1222,s=2876} | ||
{x=1679,m=44,a=2067,s=496} | ||
{x=2036,m=264,a=79,s=2244} | ||
{x=2461,m=1339,a=466,s=291} | ||
{x=2127,m=1623,a=2188,s=1013}`)).to.equal(19114); | ||
}); | ||
}); | ||
describe('Day 19: Part 2', () => { | ||
it('Should count how many distinct combitions of ratings will be accepted', () => { | ||
expect(part2(`px{a<2006:qkq,m>2090:A,rfg} | ||
pv{a>1716:R,A} | ||
lnx{m>1548:A,A} | ||
rfg{s<537:gd,x>2440:R,A} | ||
qs{s>3448:A,lnx} | ||
qkq{x<1416:A,crn} | ||
crn{x>2662:A,R} | ||
in{s<1351:px,qqz} | ||
qqz{s>2770:qs,m<1801:hdj,R} | ||
gd{a>3333:R,R} | ||
hdj{m>838:A,pv} | ||
{x=787,m=2655,a=1222,s=2876} | ||
{x=1679,m=44,a=2067,s=496} | ||
{x=2036,m=264,a=79,s=2244} | ||
{x=2461,m=1339,a=466,s=291} | ||
{x=2127,m=1623,a=2188,s=1013}`)).to.equal(167409079868000); | ||
}); | ||
}); |