114 lines
2.1 KiB
Go
114 lines
2.1 KiB
Go
package day11
|
|
|
|
import (
|
|
"internal/util"
|
|
)
|
|
|
|
const GridSize = 300
|
|
|
|
func GenerateGrid(serialNumber int) [][]int {
|
|
grid := make([][]int, GridSize)
|
|
for i := 0; i < GridSize; i++ {
|
|
grid[i] = make([]int, GridSize)
|
|
}
|
|
|
|
// Calculate the power level in each fuel cell
|
|
for y := 0; y < GridSize; y++ {
|
|
for x := 0; x < GridSize; x++ {
|
|
// Find the fuel cell's rack ID, which is its X coordinate plus 10.
|
|
rackID := (x + 1) + 10
|
|
// Begin with a power level of the rack ID times the Y coordinate.
|
|
// Increase the power level by the value of the grid serial number (your puzzle input).
|
|
// Set the power level to itself multiplied by the rack ID.
|
|
power := ((rackID * (y + 1)) + serialNumber) * rackID
|
|
|
|
// Keep only the hundreds digit of the power level (so 12345 becomes 3; numbers with no hundreds digit become 0).
|
|
power = (power % 1000) / 100
|
|
|
|
// Subtract 5 from the power level.
|
|
power -= 5
|
|
|
|
grid[y][x] = power
|
|
}
|
|
}
|
|
|
|
return grid
|
|
}
|
|
|
|
func FindBestWindow3x3(grid [][]int) (int, int) {
|
|
largest := sumNxN(grid, 0, 0, 3)
|
|
bestX := 0
|
|
bestY := 0
|
|
|
|
for x := 1; x < GridSize-2; x++ {
|
|
for y := 1; y < GridSize-2; y++ {
|
|
sum := sumNxN(grid, x, y, 3)
|
|
|
|
if sum > largest {
|
|
largest = sum
|
|
bestX = x
|
|
bestY = y
|
|
}
|
|
}
|
|
}
|
|
|
|
return bestX + 1, bestY + 1
|
|
}
|
|
|
|
func sumNxN(grid [][]int, x, y, n int) int {
|
|
total := 0
|
|
|
|
for i := 0; i < n; i++ {
|
|
for j := 0; j < n; j++ {
|
|
total += grid[y+i][x+j]
|
|
}
|
|
}
|
|
|
|
return total
|
|
}
|
|
|
|
func FindBestWindow(grid [][]int) (int, int, int) {
|
|
largest := grid[0][0]
|
|
bestX := 0
|
|
bestY := 0
|
|
bestN := 1
|
|
|
|
for x := 0; x < GridSize; x++ {
|
|
for y := 0; y < GridSize; y++ {
|
|
sum, n := findBestSquare(grid, x, y)
|
|
|
|
if sum > largest {
|
|
largest = sum
|
|
bestX = x
|
|
bestY = y
|
|
bestN = n
|
|
}
|
|
}
|
|
}
|
|
|
|
return bestX + 1, bestY + 1, bestN
|
|
}
|
|
|
|
func findBestSquare(grid [][]int, x, y int) (int, int) {
|
|
sum := grid[y][x]
|
|
bestSum := sum
|
|
bestN := 1
|
|
|
|
for n := 2; n < util.Min(GridSize-y, GridSize-x); n++ {
|
|
for i := y; i < y+n; i++ {
|
|
sum += grid[i][x+n-1]
|
|
}
|
|
|
|
for i := x; i < x+n-1; i++ {
|
|
sum += grid[y+n-1][i]
|
|
}
|
|
|
|
if sum > bestSum {
|
|
bestSum = sum
|
|
bestN = n
|
|
}
|
|
}
|
|
|
|
return bestSum, bestN
|
|
}
|