chore: add day 19 pt 1 #15
268
day19/main.go
268
day19/main.go
|
@ -32,100 +32,18 @@ func run(scan *bufio.Scanner) (*result, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is Part
|
// Is Part
|
||||||
if text[0] == '{' {
|
if p, ok := scanPart(text); ok {
|
||||||
var p part
|
|
||||||
for _, s := range strings.Split(text[1:], ",") {
|
|
||||||
a, b, _ := strings.Cut(s, "=")
|
|
||||||
i := aoc.Atoi(b)
|
|
||||||
switch a {
|
|
||||||
case "x":
|
|
||||||
p.x = i
|
|
||||||
case "m":
|
|
||||||
p.m = i
|
|
||||||
case "a":
|
|
||||||
p.a = i
|
|
||||||
case "s":
|
|
||||||
p.s = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parts = append(parts, p)
|
parts = append(parts, p)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
name, text, _ := strings.Cut(text, "{")
|
if name, r, ok := scanRule(text); ok {
|
||||||
var r []rule
|
workflows[name] = r
|
||||||
for _, s := range strings.Split(text, ",") {
|
|
||||||
if a, b, ok := strings.Cut(s, "<"); ok {
|
|
||||||
b, c, _ := strings.Cut(b, ":")
|
|
||||||
r = append(r, rule{
|
|
||||||
match: a,
|
|
||||||
op: "<",
|
|
||||||
value: aoc.Atoi(b),
|
|
||||||
queue: c,
|
|
||||||
})
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if a, b, ok := strings.Cut(s, ">"); ok {
|
|
||||||
b, c, _ := strings.Cut(b, ":")
|
|
||||||
r = append(r, rule{
|
|
||||||
match: a,
|
|
||||||
op: ">",
|
|
||||||
value: aoc.Atoi(b),
|
|
||||||
queue: c,
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// default queue comes last
|
|
||||||
r = append(r, rule{queue: s})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
workflows[name] = r
|
|
||||||
}
|
|
||||||
|
|
||||||
var rejected []part
|
|
||||||
var accepted []part
|
|
||||||
|
|
||||||
for _, p := range parts {
|
|
||||||
workflow := "in"
|
|
||||||
|
|
||||||
nextStep:
|
|
||||||
for workflow != "" {
|
|
||||||
for _, r := range workflows[workflow] {
|
|
||||||
if !r.Match(p) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
workflow = r.queue
|
|
||||||
|
|
||||||
if workflow == "A" {
|
|
||||||
accepted = append(accepted, p)
|
|
||||||
workflow = ""
|
|
||||||
break nextStep
|
|
||||||
}
|
|
||||||
if workflow == "R" {
|
|
||||||
rejected = append(rejected, p)
|
|
||||||
workflow = ""
|
|
||||||
break nextStep
|
|
||||||
}
|
|
||||||
|
|
||||||
continue nextStep
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("accepted", accepted)
|
|
||||||
fmt.Println("rejected", rejected)
|
|
||||||
|
|
||||||
var result result
|
var result result
|
||||||
|
result.valuePT1 = solveWorkflow(parts, workflows)
|
||||||
for _, p := range accepted {
|
|
||||||
result.valuePT1 += p.x
|
|
||||||
result.valuePT1 += p.m
|
|
||||||
result.valuePT1 += p.a
|
|
||||||
result.valuePT1 += p.s
|
|
||||||
}
|
|
||||||
|
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
@ -133,15 +51,73 @@ nextStep:
|
||||||
type part struct {
|
type part struct {
|
||||||
x, m, a, s int
|
x, m, a, s int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p part) String() string {
|
func (p part) String() string {
|
||||||
return fmt.Sprintf("{x:%v m:%v a:%v s:%v}", p.x,p.m,p.a,p.s)
|
return fmt.Sprintf("{x:%v m:%v a:%v s:%v}", p.x, p.m, p.a, p.s)
|
||||||
}
|
}
|
||||||
|
func scanPart(text string) (part, bool) {
|
||||||
|
var p part
|
||||||
|
|
||||||
|
// Is Part
|
||||||
|
if text[0] == '{' {
|
||||||
|
for _, s := range strings.Split(text[1:], ",") {
|
||||||
|
a, b, _ := strings.Cut(s, "=")
|
||||||
|
i := aoc.Atoi(b)
|
||||||
|
switch a {
|
||||||
|
case "x":
|
||||||
|
p.x = i
|
||||||
|
case "m":
|
||||||
|
p.m = i
|
||||||
|
case "a":
|
||||||
|
p.a = i
|
||||||
|
case "s":
|
||||||
|
p.s = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
return p, false
|
||||||
|
}
|
||||||
|
|
||||||
type rule struct {
|
type rule struct {
|
||||||
match string
|
match string
|
||||||
op string
|
op string
|
||||||
value int
|
value int
|
||||||
queue string
|
queue string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scanRule(text string) (string, []rule, bool) {
|
||||||
|
name, text, _ := strings.Cut(text, "{")
|
||||||
|
var r []rule
|
||||||
|
for _, s := range strings.Split(text, ",") {
|
||||||
|
if a, b, ok := strings.Cut(s, "<"); ok {
|
||||||
|
b, c, _ := strings.Cut(b, ":")
|
||||||
|
r = append(r, rule{
|
||||||
|
match: a,
|
||||||
|
op: "<",
|
||||||
|
value: aoc.Atoi(b),
|
||||||
|
queue: c,
|
||||||
|
})
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if a, b, ok := strings.Cut(s, ">"); ok {
|
||||||
|
b, c, _ := strings.Cut(b, ":")
|
||||||
|
r = append(r, rule{
|
||||||
|
match: a,
|
||||||
|
op: ">",
|
||||||
|
value: aoc.Atoi(b),
|
||||||
|
queue: c,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// default queue comes last
|
||||||
|
r = append(r, rule{queue: s})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return name, r, len(r) > 0
|
||||||
|
}
|
||||||
func (r rule) Match(p part) bool {
|
func (r rule) Match(p part) bool {
|
||||||
var value int
|
var value int
|
||||||
|
|
||||||
|
@ -161,17 +137,119 @@ func (r rule) Match(p part) bool {
|
||||||
if r.op == ">" && value > r.value {
|
if r.op == ">" && value > r.value {
|
||||||
return true
|
return true
|
||||||
} else if r.op == "<" && value < r.value {
|
} else if r.op == "<" && value < r.value {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false // no match
|
return false // no match
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func solveWorkflow(parts []part, workflows map[string][]rule) int {
|
||||||
|
var rejected []part
|
||||||
|
var accepted []part
|
||||||
|
|
||||||
func in(n string, haystack ...string) bool {
|
for _, p := range parts {
|
||||||
for _, h := range haystack {
|
workflow := "in"
|
||||||
if n == h {
|
|
||||||
return true
|
nextStep:
|
||||||
|
for workflow != "" {
|
||||||
|
for _, r := range workflows[workflow] {
|
||||||
|
if !r.Match(p) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
workflow = r.queue
|
||||||
|
|
||||||
|
if workflow == "A" {
|
||||||
|
accepted = append(accepted, p)
|
||||||
|
workflow = ""
|
||||||
|
break nextStep
|
||||||
|
}
|
||||||
|
if workflow == "R" {
|
||||||
|
rejected = append(rejected, p)
|
||||||
|
workflow = ""
|
||||||
|
break nextStep
|
||||||
|
}
|
||||||
|
|
||||||
|
continue nextStep
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
fmt.Println("accepted", accepted)
|
||||||
|
fmt.Println("rejected", rejected)
|
||||||
|
|
||||||
|
sum := 0
|
||||||
|
for _, p := range accepted {
|
||||||
|
sum += p.x
|
||||||
|
sum += p.m
|
||||||
|
sum += p.a
|
||||||
|
sum += p.s
|
||||||
|
}
|
||||||
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
in{s<1351:px, s>=1351:qqz}
|
||||||
|
|
||||||
|
--> px{a<2006&&(x<1416||x>2662):A, a<2006&&x>=1416&&x<=2662:R, m>2090:A, a>=2006&&m<=2090&&s<537:R||x>2440:R, a>=2006&&m<=2090&&s<537&x<=2440:A}
|
||||||
|
|
||||||
|
--> qqz{s>2770:A, m<1801&&m>838:A, m<1801&&a>1716:R, m<1801&&a<=1716:A, s<=2770&&m>=1801:R}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
in [/]
|
||||||
|
--
|
||||||
|
s<1351 -> px
|
||||||
|
s>=1351 -> qqz
|
||||||
|
|
||||||
|
px [/]
|
||||||
|
--
|
||||||
|
s<1351 -> px
|
||||||
|
|
||||||
|
a< 2006 -> qkq
|
||||||
|
m> 2090 -> A
|
||||||
|
a>=2006 -> ...
|
||||||
|
m<=2090 -> rfg
|
||||||
|
|
||||||
|
qqz [ ]
|
||||||
|
--
|
||||||
|
s>=1351 -> qqz
|
||||||
|
|
||||||
|
s> 2770 -> qs
|
||||||
|
m< 1801 -> hdj
|
||||||
|
-> R
|
||||||
|
|
||||||
|
qkq [ ]
|
||||||
|
--
|
||||||
|
s< 1351 ->
|
||||||
|
a< 2006 ->
|
||||||
|
|
||||||
|
x< 1416 -> A
|
||||||
|
x>=1416 -> crn
|
||||||
|
|
||||||
|
rfg [ ]
|
||||||
|
--
|
||||||
|
s< 1351 -> px
|
||||||
|
a>=2006 ->...
|
||||||
|
m<=2090 -> rfg
|
||||||
|
|
||||||
|
s< 537 -> gd
|
||||||
|
x> 2440 -> R
|
||||||
|
s>= 537 ->...
|
||||||
|
x<=2440 -> A
|
||||||
|
|
||||||
|
crn [ ]
|
||||||
|
--
|
||||||
|
s< 1351 -> px
|
||||||
|
a< 2006 -> qkq
|
||||||
|
x>=1416 -> crn
|
||||||
|
|
||||||
|
x> 2662 -> A
|
||||||
|
x<=2662 -> R
|
||||||
|
|
||||||
|
A
|
||||||
|
--
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user