day 21b incomplete

tried doing it, very close, I believe I have missed a very simple step or some edge case is not being run.

Value is currently way below what is expected So I either think one of the data structures is behaving badly, or I have missed a key point
This commit is contained in:
Luke Else 2021-12-22 01:02:12 +00:00
parent f406939197
commit 801d7f9a78
3 changed files with 213 additions and 0 deletions

145
day21/21b/main.go Normal file
View File

@ -0,0 +1,145 @@
package main
import (
"AdventOfCode2021/shared"
"bufio"
"fmt"
"os"
"regexp"
"strconv"
)
func main() {
//content := returnContent("../input")
content := returnContent("../testInput")
//Construct Game board... in reverse :) (Just makes it easier for stringing them together)
positions := make(map[int]*shared.GamePosition)
gameBoard := shared.GameBoard{
Start: &shared.GamePosition{
Position: 1,
Next: nil,
},
}
positions[1] = gameBoard.Start
next := gameBoard.Start
var currentPosition *shared.GamePosition
for i := 10; i > 1; i-- {
currentPosition = new(shared.GamePosition)
currentPosition.Position = i
currentPosition.Next = next
next = currentPosition
positions[i] = currentPosition
}
gameBoard.Start.Next = currentPosition
//Add Players to the game
players := make(map[int]*shared.Player)
numPlayers := 0
for _, value := range *content {
newPlayer := shared.Player{
PlayerNum: value[0],
Score: 0,
Position: positions[value[1]],
}
players[newPlayer.PlayerNum] = &newPlayer
numPlayers++
}
//Play the GAMEEEEEE
queue := shared.UniverseQueue{}
wins := make((map[int]int))
//Make the initial universe and add to queue
queue.Add(&shared.Universe{Players: players})
//Continue to process the universe
for {
current := queue.Pop()
if current == nil {
break
}
for _, p := range current.Players {
RecurseUniverse(current.Players, &queue, p.PlayerNum, wins)
}
}
fmt.Println(wins[1], wins[2])
}
func RecurseUniverse(players map[int]*shared.Player, queue *shared.UniverseQueue, player int, wins map[int]int) {
for d := 1; d <= 3; d++ {
//Create a new instance based on the current dice roll
alteredPlayer := Roll(*players[player], d)
if alteredPlayer.Score < 21 {
newUniverse := new(shared.Universe)
newPlayers := make(map[int]*shared.Player)
for _, p := range players {
newPlayer := *p
newPlayers[newPlayer.PlayerNum] = &newPlayer
}
newPlayers[player] = alteredPlayer
newUniverse.Players = newPlayers
queue.Add(newUniverse)
} else {
wins[player]++
}
}
}
func Roll(p shared.Player, diceVal int) *shared.Player {
//calculate where the position will be after n positions being moved
position := p.Position
for i := 0; i < diceVal; i++ {
position = position.Next
}
p.Position = position
p.Score += p.Position.Position
return &p
}
func returnContent(path string) *[][]int {
//read file and return it as an array of integers
file, err := os.Open(path)
var content [][]int
if err != nil {
fmt.Println("Unlucky, the file didn't open")
return &content
}
defer file.Close()
scanner := bufio.NewScanner(file)
regex, _ := regexp.Compile(`[0-9]+`)
for scanner.Scan() {
line := regex.FindAllString(scanner.Text(), 2)
nums := []int{}
for i := 0; i < len(line); i++ {
num, _ := strconv.Atoi(line[i])
nums = append(nums, num)
}
content = append(content, nums)
}
return &content
}

View File

@ -14,3 +14,42 @@ type Player struct {
Score int Score int
Position *GamePosition Position *GamePosition
} }
type Universe struct {
Players map[int]*Player
}
type QueueItem struct {
Universe *Universe
Next *QueueItem
}
type UniverseQueue struct {
Head *QueueItem
Tail *QueueItem
}
func (q *UniverseQueue) Pop() (universe *Universe) {
universe = nil
if q.Head != nil {
universe = q.Head.Universe
q.Head = q.Head.Next
if q.Head == nil {
q.Tail = nil
}
}
return
}
func (q *UniverseQueue) Add(universe *Universe) {
newUniverse := new(QueueItem)
newUniverse.Universe = universe
if q.Tail != nil {
q.Tail.Next = newUniverse
} else {
q.Head = newUniverse
}
q.Tail = newUniverse
}

29
shared/Queue.go Normal file
View File

@ -0,0 +1,29 @@
package shared
type Queue struct {
Head *Node
Tail *Node
}
func (q *Queue) Pop() (node *Node) {
node = nil
if q.Head != nil {
node = q.Head
q.Head = q.Head.Next
if q.Head == nil {
q.Tail = nil
}
}
return
}
func (q *Queue) Add(node *Node) {
if q.Tail != nil {
q.Tail.Next = node
} else {
q.Head = node
}
q.Tail = node
}