chore: add day 15
This commit is contained in:
		
							parent
							
								
									186cfb3157
								
							
						
					
					
						commit
						77a54c5563
					
				
							
								
								
									
										1
									
								
								day15/example.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								day15/example.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
 | 
				
			||||||
							
								
								
									
										1
									
								
								day15/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								day15/input.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										123
									
								
								day15/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								day15/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						_ "embed"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aoc "go.sour.is/advent-of-code-2023"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var log = aoc.Log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type result struct {
 | 
				
			||||||
 | 
						valuePT1 int
 | 
				
			||||||
 | 
						valuePT2 int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func run(scan *bufio.Scanner) (*result, error) {
 | 
				
			||||||
 | 
						r := &result{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var ops []string
 | 
				
			||||||
 | 
						for scan.Scan() {
 | 
				
			||||||
 | 
							text := scan.Text()
 | 
				
			||||||
 | 
							ops = strings.Split(text, ",")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
 | 
				
			||||||
 | 
								sum += hash(t)
 | 
				
			||||||
 | 
								return sum
 | 
				
			||||||
 | 
							}, 0, ops...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var boxen boxes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
 | 
				
			||||||
 | 
							return b.Op(op)
 | 
				
			||||||
 | 
						}, boxen, ops...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r.valuePT2 = boxen.Sum()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log(boxen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func hash(s string) int {
 | 
				
			||||||
 | 
						var sum int
 | 
				
			||||||
 | 
						for _, a := range s {
 | 
				
			||||||
 | 
							sum += int(a)
 | 
				
			||||||
 | 
							sum *= 17
 | 
				
			||||||
 | 
							sum %= 256
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sum
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type lens struct {
 | 
				
			||||||
 | 
						label string
 | 
				
			||||||
 | 
						value int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					type box []lens
 | 
				
			||||||
 | 
					type boxes [256]box
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (lis boxes) String() string {
 | 
				
			||||||
 | 
						var buf strings.Builder
 | 
				
			||||||
 | 
						buf.WriteString("Boxes:\n")
 | 
				
			||||||
 | 
						for i, b := range lis {
 | 
				
			||||||
 | 
							if len(b) > 0 {
 | 
				
			||||||
 | 
								fmt.Fprintf(&buf, "Box %d: %v\n",i, b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buf.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (lis box) String() string {
 | 
				
			||||||
 | 
						var buf strings.Builder
 | 
				
			||||||
 | 
						if len(lis) > 0 {
 | 
				
			||||||
 | 
							buf.WriteString(lis[0].String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, l := range lis[1:] {
 | 
				
			||||||
 | 
							buf.WriteString(l.String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buf.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (l lens) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("[%s %d]", l.label, l.value)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (lis boxes) Op(op string) boxes {
 | 
				
			||||||
 | 
						if a, _, ok := strings.Cut(op, "-"); ok {
 | 
				
			||||||
 | 
							i := hash(a)
 | 
				
			||||||
 | 
							pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
 | 
				
			||||||
 | 
							if pos >= 0 {
 | 
				
			||||||
 | 
								lis[i] = append(lis[i][:pos], lis[i][pos+1:]...)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if a, b, ok := strings.Cut(op, "="); ok {
 | 
				
			||||||
 | 
							i := hash(a)
 | 
				
			||||||
 | 
							pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
 | 
				
			||||||
 | 
							v := aoc.Atoi(b)
 | 
				
			||||||
 | 
							if pos == -1 {
 | 
				
			||||||
 | 
								lis[i] = append(lis[i], lens{a, v})
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								lis[i][pos].value = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return lis
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (lis boxes) Sum() int {
 | 
				
			||||||
 | 
						sum := 0
 | 
				
			||||||
 | 
						for b := range lis {
 | 
				
			||||||
 | 
							for s := range lis[b] {
 | 
				
			||||||
 | 
								sum += (b+1) * (s+1) * lis[b][s].value
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sum
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								day15/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								day15/main_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_ "embed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/matryer/is"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//go:embed example.txt
 | 
				
			||||||
 | 
					var example []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//go:embed input.txt
 | 
				
			||||||
 | 
					var input []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestExample(t *testing.T) {
 | 
				
			||||||
 | 
						is := is.New(t)
 | 
				
			||||||
 | 
						scan := bufio.NewScanner(bytes.NewReader(example))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result, err := run(scan)
 | 
				
			||||||
 | 
						is.NoErr(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Log(result)
 | 
				
			||||||
 | 
						is.Equal(result.valuePT1, 1320)
 | 
				
			||||||
 | 
						is.Equal(result.valuePT2, 145)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestSolution(t *testing.T) {
 | 
				
			||||||
 | 
						is := is.New(t)
 | 
				
			||||||
 | 
						scan := bufio.NewScanner(bytes.NewReader(input))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result, err := run(scan)
 | 
				
			||||||
 | 
						is.NoErr(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Log(result)
 | 
				
			||||||
 | 
						is.Equal(result.valuePT1, 503154)
 | 
				
			||||||
 | 
						is.Equal(result.valuePT2, 251353)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user