Day 9.1 solution.
This commit is contained in:
parent
414202f524
commit
5c52fbdc16
13
2018/day09-1.go
Normal file
13
2018/day09-1.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"internal/day09"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
numPlayers, finNum := day09.ParseInput()
|
||||||
|
_, score := day09.PlayGame(numPlayers, finNum)
|
||||||
|
fmt.Println(score)
|
||||||
|
}
|
39
2018/internal/day09/game.go
Normal file
39
2018/internal/day09/game.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package day09
|
||||||
|
|
||||||
|
// Returns the winning player's index and score
|
||||||
|
func PlayGame(numPlayers, finNum int) (int, int) {
|
||||||
|
players := make([]int, numPlayers)
|
||||||
|
|
||||||
|
// initialize the 'board'
|
||||||
|
currentMarble := &Marble{Number: 0}
|
||||||
|
currentMarble.CW = currentMarble
|
||||||
|
currentMarble.CCW = currentMarble
|
||||||
|
|
||||||
|
currentPlayer := 0
|
||||||
|
for i := 1; currentMarble.Number < finNum; i++ {
|
||||||
|
var score int
|
||||||
|
currentMarble, score = currentMarble.PlaceNewMarble(i)
|
||||||
|
players[currentPlayer] += score
|
||||||
|
|
||||||
|
currentPlayer++
|
||||||
|
if currentPlayer >= len(players) {
|
||||||
|
currentPlayer = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return findWinnerData(players)
|
||||||
|
}
|
||||||
|
|
||||||
|
func findWinnerData(players []int) (int, int) {
|
||||||
|
topScore := -1
|
||||||
|
winner := -1
|
||||||
|
|
||||||
|
for player, score := range players {
|
||||||
|
if score > topScore {
|
||||||
|
topScore = score
|
||||||
|
winner = player
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return winner, topScore
|
||||||
|
}
|
55
2018/internal/day09/marbles.go
Normal file
55
2018/internal/day09/marbles.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package day09
|
||||||
|
|
||||||
|
type Marble struct {
|
||||||
|
Number int
|
||||||
|
CW *Marble
|
||||||
|
CCW *Marble
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the new current marble and the score to add.
|
||||||
|
func (m *Marble) PlaceNewMarble(number int) (*Marble, int) {
|
||||||
|
// if the marble that is about to be placed has a number which is a multiple
|
||||||
|
// of 23, the current player keeps the marble they would have placed, adding
|
||||||
|
// it to their score. In addition, the marble 7 marbles counter-clockwise
|
||||||
|
// from the current marble is removed from the circle and also added to the
|
||||||
|
// current player's score. The marble located immediately clockwise of the
|
||||||
|
// marble that was removed becomes the new current marble.
|
||||||
|
if number%23 == 0 {
|
||||||
|
score := number
|
||||||
|
cursor := m
|
||||||
|
for i := 0; i < 7; i++ {
|
||||||
|
cursor = cursor.CCW
|
||||||
|
}
|
||||||
|
score += cursor.Number
|
||||||
|
cursor = cursor.Remove()
|
||||||
|
return cursor, score
|
||||||
|
}
|
||||||
|
|
||||||
|
// [Insert the marble] between the marbles that are 1 and 2
|
||||||
|
// marbles clockwise of the current marble.
|
||||||
|
// The marble that was just placed then becomes the current marble.
|
||||||
|
|
||||||
|
// first create the marble and populate its fields correctly
|
||||||
|
newMarble := &Marble{Number: number}
|
||||||
|
cursor := m.CW
|
||||||
|
newMarble.CCW = cursor
|
||||||
|
newMarble.CW = cursor.CW
|
||||||
|
|
||||||
|
// now sync up the pointers in the adjacent marbles
|
||||||
|
newMarble.CCW.CW = newMarble
|
||||||
|
newMarble.CW.CCW = newMarble
|
||||||
|
return newMarble, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Marble) Remove() *Marble {
|
||||||
|
// removes the marble from the list, repairing links. Returns the
|
||||||
|
// marble immediately CW of this one.
|
||||||
|
|
||||||
|
// link the two newly-adjacent marbles.
|
||||||
|
ccw := m.CCW
|
||||||
|
cw := m.CW
|
||||||
|
ccw.CW = cw
|
||||||
|
cw.CCW = ccw
|
||||||
|
|
||||||
|
return cw
|
||||||
|
}
|
25
2018/internal/day09/util.go
Normal file
25
2018/internal/day09/util.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package day09
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseInput() (int, int) {
|
||||||
|
rawData := strings.TrimSpace(util.ReadInput()[0])
|
||||||
|
data := strings.Split(rawData, " ")
|
||||||
|
|
||||||
|
players, err := strconv.Atoi(data[0])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastNum, err := strconv.Atoi(data[6])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return players, lastNum
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user