2020 Day 22 Complete
This commit is contained in:
parent
aaf3054c8a
commit
5a37a6e964
53
2020/day22/input
Normal file
53
2020/day22/input
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Player 1:
|
||||||
|
4
|
||||||
|
25
|
||||||
|
3
|
||||||
|
11
|
||||||
|
2
|
||||||
|
29
|
||||||
|
41
|
||||||
|
23
|
||||||
|
30
|
||||||
|
21
|
||||||
|
50
|
||||||
|
8
|
||||||
|
1
|
||||||
|
24
|
||||||
|
27
|
||||||
|
10
|
||||||
|
42
|
||||||
|
43
|
||||||
|
38
|
||||||
|
15
|
||||||
|
18
|
||||||
|
13
|
||||||
|
32
|
||||||
|
37
|
||||||
|
34
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
12
|
||||||
|
6
|
||||||
|
36
|
||||||
|
35
|
||||||
|
40
|
||||||
|
47
|
||||||
|
31
|
||||||
|
9
|
||||||
|
46
|
||||||
|
49
|
||||||
|
19
|
||||||
|
16
|
||||||
|
5
|
||||||
|
26
|
||||||
|
39
|
||||||
|
48
|
||||||
|
7
|
||||||
|
44
|
||||||
|
45
|
||||||
|
20
|
||||||
|
17
|
||||||
|
14
|
||||||
|
33
|
||||||
|
28
|
||||||
|
22
|
193
2020/day22/main.go
Normal file
193
2020/day22/main.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
var debugLevel int
|
||||||
|
|
||||||
|
const (
|
||||||
|
debugLo = 1
|
||||||
|
debugMd = 2
|
||||||
|
debugHi = 3
|
||||||
|
debugNo = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("# Day 22")
|
||||||
|
inp := h.StdinToStringSlice()
|
||||||
|
|
||||||
|
debugLevel = h.Atoi(h.OptArgNumber(2, "-1"))
|
||||||
|
|
||||||
|
solve(inp, h.Atoi(h.OptArgNumber(1, "2")))
|
||||||
|
}
|
||||||
|
|
||||||
|
func print(s string, lvl int) {
|
||||||
|
if debugLevel != -1 && lvl >= debugLevel {
|
||||||
|
fmt.Print(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func solve(inp []string, part int) {
|
||||||
|
var player int
|
||||||
|
decks := make(map[int]*Deck)
|
||||||
|
for k := range inp {
|
||||||
|
if strings.TrimSpace(inp[k]) == "" {
|
||||||
|
continue
|
||||||
|
} else if strings.HasPrefix(inp[k], "Player ") {
|
||||||
|
player = h.Atoi(inp[k][7 : len(inp[k])-1])
|
||||||
|
decks[player] = &Deck{Player: player}
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
decks[player].Add(h.Atoi(inp[k]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if part == 1 {
|
||||||
|
solveNormal(decks[1], decks[2])
|
||||||
|
} else {
|
||||||
|
solveRecursive(decks[1], decks[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveNormal(deck1, deck2 *Deck) {
|
||||||
|
round := 1
|
||||||
|
winner := Winner(deck1, deck2)
|
||||||
|
for winner == -1 {
|
||||||
|
|
||||||
|
print(fmt.Sprintf("-- Round %d --\n%s\n%s\n", round, deck1, deck2), debugLo)
|
||||||
|
|
||||||
|
cmp1 := deck1.Draw()
|
||||||
|
cmp2 := deck2.Draw()
|
||||||
|
print(fmt.Sprintf("Player 1 plays: %d\nPlayer 2 plays: %d\n", cmp1, cmp2), debugLo)
|
||||||
|
if cmp1 > cmp2 {
|
||||||
|
print(fmt.Sprintln("Player 1 wins the round!"), debugLo)
|
||||||
|
deck1.Add(cmp1, cmp2)
|
||||||
|
} else if cmp2 > cmp1 {
|
||||||
|
print(fmt.Sprintln("Player 2 wins the round!"), debugLo)
|
||||||
|
deck2.Add(cmp2, cmp1)
|
||||||
|
}
|
||||||
|
round++
|
||||||
|
winner = Winner(deck1, deck2)
|
||||||
|
}
|
||||||
|
fmt.Printf("== Post-game results ==\n%s\n%s\n", deck1, deck2)
|
||||||
|
var score int
|
||||||
|
if winner == 1 {
|
||||||
|
score = deck1.Score()
|
||||||
|
} else {
|
||||||
|
score = deck2.Score()
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("## Part 1:\nAnswer: ", score)
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveRecursive(deck1, deck2 *Deck) {
|
||||||
|
winner := RPlayGame(deck1, deck2)
|
||||||
|
|
||||||
|
fmt.Printf("== Post-game results ==\n%s\n%s\n", deck1, deck2)
|
||||||
|
var score int
|
||||||
|
if winner == 1 {
|
||||||
|
score = deck1.Score()
|
||||||
|
} else {
|
||||||
|
score = deck2.Score()
|
||||||
|
}
|
||||||
|
fmt.Println("## Part 2:\nAnswer: ", score)
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalGames int
|
||||||
|
|
||||||
|
func RPlayGame(deck1, deck2 *Deck) int {
|
||||||
|
var history []string
|
||||||
|
var repeat bool
|
||||||
|
for deck1.Len() > 0 && deck2.Len() > 0 {
|
||||||
|
history, repeat = RPlayRound(deck1, deck2, history)
|
||||||
|
if repeat {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Winner(deck1, deck2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RPlayRound(deck1, deck2 *Deck, history []string) ([]string, bool) {
|
||||||
|
status := fmt.Sprintf("%s%s", deck1, deck2)
|
||||||
|
if h.StringSliceContains(history, status) {
|
||||||
|
return history, true
|
||||||
|
}
|
||||||
|
nextHistory := append(history, status)
|
||||||
|
c1, c2 := deck1.Draw(), deck2.Draw()
|
||||||
|
if deck1.Len() >= c1 && deck2.Len() >= c2 {
|
||||||
|
winner := RPlayGame(deck1.Copy(c1), deck2.Copy(c2))
|
||||||
|
switch winner {
|
||||||
|
case 1:
|
||||||
|
deck1.Add(c1, c2)
|
||||||
|
case 2:
|
||||||
|
deck2.Add(c2, c1)
|
||||||
|
}
|
||||||
|
return nextHistory, false
|
||||||
|
}
|
||||||
|
if c1 > c2 {
|
||||||
|
deck1.Add(c1, c2)
|
||||||
|
} else {
|
||||||
|
deck2.Add(c2, c1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextHistory, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Winner(deck1, deck2 *Deck) int {
|
||||||
|
if deck2.Empty() {
|
||||||
|
return 1
|
||||||
|
} else if deck1.Empty() {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
type Deck struct {
|
||||||
|
Player int
|
||||||
|
cards []int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Add(card ...int) {
|
||||||
|
d.cards = append(d.cards, card...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Draw() int {
|
||||||
|
var ret int
|
||||||
|
ret, d.cards = d.cards[0], d.cards[1:]
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Empty() bool {
|
||||||
|
return len(d.cards) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Len() int {
|
||||||
|
return len(d.cards)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Score() int {
|
||||||
|
var ret int
|
||||||
|
for k := len(d.cards) - 1; k >= 0; k-- {
|
||||||
|
ret = ret + (d.cards[k] * (len(d.cards) - k))
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Deck) Copy(num int) *Deck {
|
||||||
|
ret := Deck{
|
||||||
|
Player: d.Player,
|
||||||
|
}
|
||||||
|
for k := 0; k < num && k < len(d.cards); k++ {
|
||||||
|
ret.Add(d.cards[k])
|
||||||
|
}
|
||||||
|
return &ret
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Deck) String() string {
|
||||||
|
return fmt.Sprintf("Player %d's deck: %v", d.Player, d.cards)
|
||||||
|
}
|
13
2020/day22/testinput
Normal file
13
2020/day22/testinput
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Player 1:
|
||||||
|
9
|
||||||
|
2
|
||||||
|
6
|
||||||
|
3
|
||||||
|
1
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
5
|
||||||
|
8
|
||||||
|
4
|
||||||
|
7
|
||||||
|
10
|
8
2020/day22/testinput2
Normal file
8
2020/day22/testinput2
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Player 1:
|
||||||
|
43
|
||||||
|
19
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
2
|
||||||
|
29
|
||||||
|
14
|
Loading…
Reference in New Issue
Block a user