chore: organization day19
This commit is contained in:
		
							parent
							
								
									39c6f8ed4d
								
							
						
					
					
						commit
						62f8338227
					
				
							
								
								
									
										268
									
								
								day19/main.go
									
									
									
									
									
								
							
							
						
						
									
										268
									
								
								day19/main.go
									
									
									
									
									
								
							@ -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
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user