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 ") 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 }