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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user