22 done
This commit is contained in:
parent
010a843471
commit
44fb58ff14
155
22/main.go
Normal file
155
22/main.go
Normal file
@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
partOne()
|
||||
duration := time.Since(start)
|
||||
partTwo()
|
||||
duration2 := time.Since(start)
|
||||
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
||||
}
|
||||
|
||||
type deck struct {
|
||||
cards []int
|
||||
}
|
||||
|
||||
type cacheKey struct {
|
||||
one int
|
||||
two int
|
||||
}
|
||||
|
||||
func countWinningDeck(deck []int) int {
|
||||
sum := 0
|
||||
for i := range deck {
|
||||
sum = sum + ((len(deck) - i) * deck[i])
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// return values is who won/their score: true for player one, false for player two
|
||||
func playCombat(one, two []int) (bool, int) {
|
||||
round := 0
|
||||
for len(one) > 0 && len(two) > 0 {
|
||||
round = round + 1
|
||||
if one[0] > two[0] {
|
||||
one = append(one[1:], one[0], two[0])
|
||||
two = two[1:]
|
||||
} else if one[0] < two[0] {
|
||||
two = append(two[1:], two[0], one[0])
|
||||
one = one[1:]
|
||||
}
|
||||
}
|
||||
if len(one) == 0 {
|
||||
return false, countWinningDeck(two)
|
||||
}
|
||||
return true, countWinningDeck(one)
|
||||
}
|
||||
|
||||
func playRecursiveCombat(one, two []int) (bool, int) {
|
||||
loopCache := make(map[cacheKey]bool, 0)
|
||||
round := 0
|
||||
for len(one) > 0 && len(two) > 0 {
|
||||
// check for loops
|
||||
if loopCache[cacheKey{one: countWinningDeck(one), two: countWinningDeck(two)}] {
|
||||
return true, countWinningDeck(one)
|
||||
}
|
||||
loopCache[cacheKey{one: countWinningDeck(one), two: countWinningDeck(two)}] = true
|
||||
|
||||
// otherwise, play a round
|
||||
round = round + 1
|
||||
if len(one[1:]) >= one[0] && len(two[1:]) >= two[0] {
|
||||
// fuckin' go slice internals
|
||||
subDeckOne := make([]int, len(one))
|
||||
subDeckTwo := make([]int, len(two))
|
||||
copy(subDeckOne, one)
|
||||
copy(subDeckTwo, two)
|
||||
winner, _ := playRecursiveCombat(subDeckOne[1:one[0]+1], subDeckTwo[1:two[0]+1])
|
||||
if winner { // p1 wins
|
||||
one = append(one[1:], one[0], two[0])
|
||||
two = two[1:]
|
||||
} else { // p2 wins
|
||||
two = append(two[1:], two[0], one[0])
|
||||
one = one[1:]
|
||||
}
|
||||
} else if one[0] > two[0] {
|
||||
one = append(one[1:], one[0], two[0])
|
||||
two = two[1:]
|
||||
} else if one[0] < two[0] {
|
||||
two = append(two[1:], two[0], one[0])
|
||||
one = one[1:]
|
||||
}
|
||||
}
|
||||
if len(one) == 0 {
|
||||
return false, countWinningDeck(two)
|
||||
}
|
||||
return true, countWinningDeck(one)
|
||||
}
|
||||
|
||||
func partOne() {
|
||||
f, _ := os.Open("input")
|
||||
reader := bufio.NewReader(f)
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
// deal the decks
|
||||
playerone := deck{}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line == "" {
|
||||
break
|
||||
}
|
||||
i, err := strconv.Atoi(line)
|
||||
if err == nil {
|
||||
playerone.cards = append(playerone.cards, i)
|
||||
}
|
||||
}
|
||||
playertwo := deck{}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
i, err := strconv.Atoi(line)
|
||||
if err == nil {
|
||||
playertwo.cards = append(playertwo.cards, i)
|
||||
}
|
||||
}
|
||||
|
||||
// play a game and determine a winner
|
||||
_, score := playCombat(playerone.cards, playertwo.cards)
|
||||
fmt.Println(score)
|
||||
}
|
||||
|
||||
func partTwo() {
|
||||
f, _ := os.Open("testinput")
|
||||
reader := bufio.NewReader(f)
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
// deal the decks
|
||||
playerone := deck{}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line == "" {
|
||||
break
|
||||
}
|
||||
i, err := strconv.Atoi(line)
|
||||
if err == nil {
|
||||
playerone.cards = append(playerone.cards, i)
|
||||
}
|
||||
}
|
||||
playertwo := deck{}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
i, err := strconv.Atoi(line)
|
||||
if err == nil {
|
||||
playertwo.cards = append(playertwo.cards, i)
|
||||
}
|
||||
}
|
||||
|
||||
_, score := playRecursiveCombat(playerone.cards, playertwo.cards)
|
||||
fmt.Println(score)
|
||||
}
|
Loading…
Reference in New Issue
Block a user