package main import ( "fmt" "strings" ) const ( gridX = 300 gridY = 300 ) var gridSize = gridX * gridY type Puzzle struct { Serial int Cells []int } func FuelAtCell(serial, x, y int) int { id := x + 10 fuel := id * y fuel += serial fuel *= id fuel /= 100 fuel %= 10 fuel &= 0xf fuel -= 5 return fuel } func NewPuzzle(serial int) Puzzle { p := Puzzle{ Serial: serial, Cells: make([]int, gridSize), } for y := 1; y < gridY+1; y++ { for x := 1; x < gridX+1; x++ { i := ((y - 1) * gridX) + (x - 1) p.Cells[i] = FuelAtCell(p.Serial, x, y) } } return p } func (p Puzzle) String() string { output := strings.Builder{} for y := 0; y < gridY; y++ { for x := 0; x < gridX; x++ { i := (y * gridX) + x output.WriteString(fmt.Sprintf("%3d", p.Cells[i])) } output.WriteByte('\n') } return output.String() } func (p *Puzzle) Solution1() (int, int) { var rx, ry int largest := 0 for y := 0; y < gridY-3; y++ { for x := 0; x < gridX-3; x++ { total := 0 for yy := y; yy < y+3; yy++ { for xx := x; xx < x+3; xx++ { i := (yy * gridY) + xx total += p.Cells[i] } } if total > largest { largest = total rx = x + 1 ry = y + 1 } } } return rx, ry } func (p *Puzzle) Solution2() (int, int, int) { var rx, ry int largestTotal := 0 largestGrid := 0 type chanStruct struct { total int x, y, s int } done := make(chan chanStruct) for grid := 0; grid < 300; grid++ { go (func(grid int) { var rx, ry int largestTotal := 0 fmt.Printf("Grid %dx%d\n", grid, grid) for y := 0; y < gridY-grid; y++ { for x := 0; x < gridX-grid; x++ { total := 0 for yy := y; yy < y+grid; yy++ { for xx := x; xx < x+grid; xx++ { i := (yy * gridY) + xx total += p.Cells[i] } } if total > largestTotal { largestTotal = total rx = x + 1 ry = y + 1 } } } done <- chanStruct{ total: largestTotal, x: rx, y: ry, s: grid, } })(grid) } count := 0 for count < 300 { result := <-done if result.total > largestTotal { largestTotal = result.total largestGrid = result.s rx = result.x ry = result.y } fmt.Printf("%d %dx%d -> %d,%d(%d)\n", count, result.s, result.s, result.x, result.y, result.total) count++ } return rx, ry, largestGrid } func main() { p := NewPuzzle(7315) // p := NewPuzzle(42) fmt.Println(p.Solution1()) fmt.Println(p.Solution2()) }