2018 Day09 Complete
This commit is contained in:
143
2018/day09/day09.go
Normal file
143
2018/day09/day09.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var playerCount, marbleCount int
|
||||
var game *Game
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 3 {
|
||||
fmt.Println("Usage: day09 <# players> <# marbles>")
|
||||
os.Exit(1)
|
||||
}
|
||||
playerCount, marbleCount = Atoi(os.Args[1]), Atoi(os.Args[2])
|
||||
part1()
|
||||
}
|
||||
|
||||
func part1() {
|
||||
g := NewGame(playerCount, marbleCount)
|
||||
for i := 1; i <= marbleCount; i++ {
|
||||
if i%23 == 0 {
|
||||
g.score(i)
|
||||
} else {
|
||||
g.insertMarble(&Marble{value: i})
|
||||
}
|
||||
g.nextPlayer()
|
||||
}
|
||||
fmt.Println("* Winner *")
|
||||
g.printWinner()
|
||||
}
|
||||
|
||||
type Game struct {
|
||||
playerCount, marbleCount int
|
||||
currentPlayer int
|
||||
scores map[int]int
|
||||
|
||||
currentMarble *Marble
|
||||
}
|
||||
|
||||
func NewGame(players, marbles int) *Game {
|
||||
startMarble := &Marble{
|
||||
value: 0,
|
||||
}
|
||||
startMarble.clockwise = startMarble
|
||||
startMarble.widdershins = startMarble
|
||||
return &Game{
|
||||
playerCount: players,
|
||||
marbleCount: marbles,
|
||||
currentPlayer: 1,
|
||||
scores: make(map[int]int),
|
||||
currentMarble: startMarble,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) insertMarble(m *Marble) {
|
||||
m.clockwise = g.currentMarble.clockwise.clockwise
|
||||
m.widdershins = g.currentMarble.clockwise
|
||||
g.currentMarble.clockwise.clockwise.widdershins = m
|
||||
g.currentMarble.clockwise.clockwise = m
|
||||
g.currentMarble = m
|
||||
}
|
||||
|
||||
func (g *Game) score(val int) {
|
||||
g.scores[g.currentPlayer] += val
|
||||
for i := 0; i < 6; i++ {
|
||||
g.currentMarble = g.currentMarble.widdershins
|
||||
}
|
||||
// Remove g.currentMarble.widdershins
|
||||
// adding it's value to the current player's score
|
||||
rem := g.currentMarble.widdershins
|
||||
g.currentMarble.widdershins = rem.widdershins
|
||||
g.currentMarble.widdershins.clockwise = g.currentMarble
|
||||
g.scores[g.currentPlayer] += rem.value
|
||||
}
|
||||
|
||||
func (g *Game) nextPlayer() {
|
||||
if g.currentPlayer == g.playerCount {
|
||||
g.currentPlayer = 1
|
||||
} else {
|
||||
g.currentPlayer++
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) printState() {
|
||||
fmt.Printf("[%d] ", g.currentPlayer)
|
||||
p := *g.currentMarble
|
||||
for p.value != 0 {
|
||||
// Find the '0' marble
|
||||
p = *p.clockwise
|
||||
}
|
||||
if p.value == g.currentMarble.value {
|
||||
fmt.Printf("(%d)", p.value)
|
||||
} else {
|
||||
fmt.Printf(" %d ", p.value)
|
||||
}
|
||||
p = *p.clockwise
|
||||
for p.value != 0 {
|
||||
if p.value == g.currentMarble.value {
|
||||
fmt.Printf("(%d)", p.value)
|
||||
} else {
|
||||
fmt.Printf(" %d ", p.value)
|
||||
}
|
||||
p = *p.clockwise
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func (g *Game) printScores() {
|
||||
for i := 1; i <= g.playerCount; i++ {
|
||||
fmt.Println(i, ":", g.scores[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) printWinner() {
|
||||
var top int
|
||||
var winner int
|
||||
for k, v := range g.scores {
|
||||
if v > top {
|
||||
top = v
|
||||
winner = k
|
||||
}
|
||||
}
|
||||
fmt.Println(winner, ":", top)
|
||||
}
|
||||
|
||||
type Marble struct {
|
||||
value int
|
||||
clockwise *Marble
|
||||
widdershins *Marble
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user