package main import ( "bufio" "fmt" "os" "strings" ) var lineSize = 2000 var offset = 10 type Rule struct { Match []byte Out byte } type Puzzle struct { Plants []byte Rules []Rule } func sliceEqual(a, b []byte) bool { if len(a) != len(b) { return false } for t := 0; t < len(a); t++ { if a[t] != b[t] { return false } } return true } func (p *Puzzle) findMatch(pattern []byte) byte { for _, r := range p.Rules { if sliceEqual(r.Match, pattern) { return r.Out } } return '.' } func (p *Puzzle) Solution1() int { fmt.Printf("%2d %s\n", 0, string(p.Plants)) for i := 0; i < 20; i++ { out := make([]byte, lineSize) copy(out, p.Plants) for t := 0; t < lineSize-offset; t++ { pattern := p.Plants[t : t+5] out[t+2] = p.findMatch(pattern) } p.Plants = out fmt.Printf("%2d %s\n", i+1, string(p.Plants)) } points := 0 for t, c := range p.Plants { if c == '#' { points += (t - offset) } } return points } func (p *Puzzle) Solution2() int { points := 0 lastPoints := 0 for i := 0; i < 200; i++ { fmt.Println(i, points, points-lastPoints) out := make([]byte, lineSize) for t := range p.Plants { out[t] = '.' } for t := 0; t < lineSize-offset; t++ { pattern := p.Plants[t : t+5] out[t+2] = p.findMatch(pattern) } p.Plants = out fmt.Printf("%2d %s\n", i+1, string(p.Plants)) lastPoints = points points = 0 for t, c := range p.Plants { if c == '#' { points += (t - offset) if t > lineSize-20 { fmt.Println("oh fuck") return 0 } } } } return points } func main() { input, err := os.Open("input.txt") if err != nil { panic(err.Error()) } defer input.Close() scanner := bufio.NewScanner(input) p := Puzzle{ Plants: make([]byte, lineSize), Rules: make([]Rule, 0, 10), } scanner.Scan() initial := []byte(strings.Split(scanner.Text(), ": ")[1]) for t := range p.Plants { p.Plants[t] = '.' } for t := range initial { p.Plants[t+offset] = initial[t] } scanner.Scan() for scanner.Scan() { ruleParts := strings.Split(scanner.Text(), " => ") p.Rules = append(p.Rules, Rule{ Match: []byte(ruleParts[0]), Out: []byte(ruleParts[1])[0], }) } if err := scanner.Err(); err != nil { panic(err.Error()) } /* palette := []color.Color{ color.RGBA{0, 0, 0, 0xff}, color.RGBA{0xff, 0xff, 0xff, 0xff}, } size := image.Rect(0, 0, 128, 128) images := make([]*image.Paletted, 10) delays := make([]int, 10) for t := 0; t < 10; t++ { images[t] = image.NewPaletted(size, palette) for y := 0; y < 128; y++ { for x := 0; x < 128; x++ { c := byte((x + t) ^ (y + t)) images[t].Set(x, y, color.RGBA{ c, c, c, 0xff, }) } } } f, err := os.OpenFile("out.gif", os.O_WRONLY|os.O_CREATE, 0666) if err != nil { panic(err) } defer f.Close() gif.EncodeAll(f, &gif.GIF{ Image: images, Delay: delays, }) */ // fmt.Println(p.Solution1()) fmt.Println(p.Solution2()) }