Completed part 2 of Day 19 puzzle with a lot of help from https://github.com/rumkugel13 to debug my code (wouldn't have finished it otherwise)

main
oabrivard 2 years ago
parent e6f5aef706
commit d8eddf80e3

@ -64,6 +64,7 @@ func ParseWorkflows(lines []string) map[string]Workflow {
wf = append(wf, Rule{
category: 'F',
operator: 0,
action: wfLast,
})
@ -167,3 +168,91 @@ func Part1(lines []string) int {
return sum
}
func countParts(mins Part, maxs Part) int {
result := 1
result *= maxs.xVal - mins.xVal + 1
result *= maxs.mVal - mins.mVal + 1
result *= maxs.aVal - mins.aVal + 1
result *= maxs.sVal - mins.sVal + 1
return result
}
func traverseWF(wfName string, workflows map[string]Workflow, mins Part, maxs Part) int {
if wfName == "R" {
return 0
}
if wfName == "A" {
return countParts(mins, maxs)
}
wf := workflows[wfName]
result := 0
for _, rule := range wf {
nextMins := mins
nextMaxs := maxs
switch rule.operator {
case 0:
result += traverseWF(rule.action, workflows, mins, maxs)
case '<':
switch rule.category {
case 'x':
nextMaxs.xVal = rule.value - 1
mins.xVal = rule.value
case 'm':
nextMaxs.mVal = rule.value - 1
mins.mVal = rule.value
case 'a':
nextMaxs.aVal = rule.value - 1
mins.aVal = rule.value
case 's':
nextMaxs.sVal = rule.value - 1
mins.sVal = rule.value
}
result += traverseWF(rule.action, workflows, nextMins, nextMaxs)
case '>':
switch rule.category {
case 'x':
nextMins.xVal = rule.value + 1
maxs.xVal = rule.value
case 'm':
nextMins.mVal = rule.value + 1
maxs.mVal = rule.value
case 'a':
nextMins.aVal = rule.value + 1
maxs.aVal = rule.value
case 's':
nextMins.sVal = rule.value + 1
maxs.sVal = rule.value
}
result += traverseWF(rule.action, workflows, nextMins, nextMaxs)
}
}
return result
}
func Part2(lines []string) int {
idx := 0
for i, line := range lines {
if strings.TrimSpace(line) == "" {
idx = i
break
}
}
workflows := ParseWorkflows(lines[:idx])
fmt.Println(len(workflows))
mins := Part{1, 1, 1, 1}
maxs := Part{4000, 4000, 4000, 4000}
result := traverseWF("in", workflows, mins, maxs)
return result
}

@ -81,3 +81,41 @@ func TestPart1WithInput(t *testing.T) {
t.Fatalf("expected 575412, got %d", result)
}
}
func TestPart2(t *testing.T) {
lines := []string{
"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}",
}
result := Part2(lines)
if result != 167409079868000 {
t.Fatalf("expected 167409079868000, got %d", result)
}
}
func TestPart2WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := Part2(lines)
if result != 126107942006821 {
t.Fatalf("expected 126107942006821, got %d", result)
}
}

Loading…
Cancel
Save