adventofcode/2018/day11/day11.go
2018-12-03 19:49:23 +00:00

120 lines
2.3 KiB
Go

package main
import (
"fmt"
"log"
"os"
"strconv"
)
const (
MaxInt = int(^uint(0) >> 1)
MinInt = -MaxInt - 1
)
var timeMachine *TimeMachine
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: day11 <serial #>")
os.Exit(1)
}
timeMachine = &TimeMachine{
serial: Atoi(os.Args[1]),
fuelLevels: make(map[string]int),
}
fmt.Println(timeMachine.calcSquareFuelLevel(90, 269, 16))
os.Exit(0)
highest := MinInt
highestX, highestY := 0, 0
highestSize := 1
for size := 1; size <= 20; size++ {
fmt.Println(size)
for i := 0; i < 300-size; i++ {
for j := 0; j < 300-size; j++ {
w := timeMachine.getSquareLevel(i, j, size)
if w > highest {
highestX, highestY = i, j
highest = w
highestSize = size
}
}
}
}
fmt.Print(highestX, ",", highestY, ",", highestSize, " : ", highest, "\n")
}
type TimeMachine struct {
serial int
fuelLevels map[string]int
}
func (t *TimeMachine) getKeyForSquare(x, y, size int) string {
bx := strconv.Itoa(x)
by := strconv.Itoa(y)
bs := strconv.Itoa(size)
return bx + "," + by + "," + bs
}
func (t *TimeMachine) setSquareLevel(x, y, size, val int) {
t.fuelLevels[t.getKeyForSquare(x, y, size)] = val
}
func (t *TimeMachine) getSquareLevel(x, y, size int) int {
key := t.getKeyForSquare(x, y, size)
if ret, ok := t.fuelLevels[key]; !ok {
t.fuelLevels[key] = t.calcSquareLevel(x, y, size)
return t.fuelLevels[key]
} else {
return ret
}
}
func (t *TimeMachine) calcSquareLevel(x, y, size int) int {
if size == 1 {
return t.calcFuelLevel(x, y)
}
ret := t.getSquareLevel(x, y, size-1)
for wx := x; wx < wx+size; wx++ {
ret += t.getSquareLevel(wx, y+size-1, 1)
}
for wy := y; wy < wy+size-1; wy++ {
ret += t.getSquareLevel(x+size-1, wy, 1)
}
return ret
}
func (t *TimeMachine) calcFuelLevel(x, y int) int {
rackId := x + 10
startingLevel := rackId * y
currLevel := startingLevel + t.serial
currLevel *= rackId
var ret int
if currLevel < 100 {
ret = -5
} else {
ret = ((currLevel / 100) % 10) - 5
}
return ret
}
func (t *TimeMachine) calcSquareFuelLevel(x, y, size int) int {
var ret int
for i := 0; i < size; i++ {
for j := 0; j < size; j++ {
ret += t.calcFuelLevel(i, j)
}
}
return ret
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}