chore: organization day19

pull/21/head
xuu 2023-12-30 19:46:23 -07:00
parent 39c6f8ed4d
commit 62f8338227
2 changed files with 182 additions and 95 deletions

View File

@ -32,100 +32,18 @@ func run(scan *bufio.Scanner) (*result, error) {
}
// Is Part
if text[0] == '{' {
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
}
}
if p, ok := scanPart(text); ok {
parts = append(parts, p)
continue
}
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
}
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
}
if name, r, ok := scanRule(text); ok {
workflows[name] = r
}
}
fmt.Println("accepted", accepted)
fmt.Println("rejected", rejected)
var result result
for _, p := range accepted {
result.valuePT1 += p.x
result.valuePT1 += p.m
result.valuePT1 += p.a
result.valuePT1 += p.s
}
result.valuePT1 = solveWorkflow(parts, workflows)
return &result, nil
}
@ -133,15 +51,73 @@ nextStep:
type part struct {
x, m, a, s int
}
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 {
match string
op string
value int
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 {
var value int
@ -161,17 +137,119 @@ func (r rule) Match(p part) bool {
if r.op == ">" && value > r.value {
return true
} else if r.op == "<" && value < r.value {
return true
}
return false // no match
return true
}
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 _, h := range haystack {
if n == h {
return true
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
}
}
}
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
--
*/

9
set.go
View File

@ -57,3 +57,12 @@ func (m *defaultMap[K, V]) Items() []pair[K, V] {
}
return items
}
func In[C comparable](n C, haystack ...C) bool {
for _, h := range haystack {
if n == h {
return true
}
}
return false
}