aoc-2020/d15/main.go

95 lines
1.7 KiB
Go

package main
import "fmt"
type game struct {
turn, lastNumber int
history map[int]int
}
func newGame(startingNumbers []int) *game {
g := game{0, 0, map[int]int{}}
for _, n := range startingNumbers {
g.history[g.lastNumber] = g.turn
g.turn++
g.lastNumber = n
}
return &g
}
func (g *game) takeTurn() (int, int) {
// fmt.Printf("> Starting turn %d. last: %d\n", g.turn+1, g.lastNumber)
// fmt.Printf(">> state %+v\n", g)
var number int
// Get the new number
if t, ok := g.history[g.lastNumber]; ok {
// fmt.Printf(">> We've seen %d before!\n", g.lastNumber)
// Last number was seen
number = g.turn - t
} else {
// Otherwise the number is zero
number = 0
}
// Store the last turn in history
g.history[g.lastNumber] = g.turn
// Go to the next turn
g.turn++
g.lastNumber = number
// fmt.Printf(">> Incrementing turn and updating state %+v\n", g)
// fmt.Printf("Turn %d spoke \"%d\"\n", g.turn, g.lastNumber)
return g.turn, g.lastNumber
}
func (g *game) turnTo(targetTurn int) int {
var n int
for g.turn < targetTurn {
_, n = g.takeTurn()
}
return n
}
func part1() {
numbers := []int{16, 12, 1, 0, 15, 7, 11}
// numbers := []int{0, 3, 6}
g := newGame(numbers)
fmt.Println(g)
t, n := g.takeTurn()
for t < 2020 {
t, n = g.takeTurn()
}
fmt.Printf("Part 1: Number on turn %d is %d\n", t, n)
}
func part2() {
numbers := []int{16, 12, 1, 0, 15, 7, 11}
// numbers := []int{0, 3, 6}
g := newGame(numbers)
fmt.Println(g)
t, n := g.takeTurn()
for t < 30000000 {
t, n = g.takeTurn()
}
fmt.Printf("Part 2: Number on turn %d is %d\n", t, n)
}
func main() {
fmt.Println(newGame([]int{16, 12, 1, 0, 15, 7, 11}).turnTo(2020))
fmt.Println(newGame([]int{16, 12, 1, 0, 15, 7, 11}).turnTo(30000000))
part1()
part2()
}