diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 75c643d..5b1d307 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -11,8 +11,11 @@
+
+
+
-
+
@@ -53,7 +56,7 @@
-
+
@@ -184,6 +187,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -287,6 +300,7 @@
+
@@ -311,39 +325,59 @@
-
+
-
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -364,9 +398,20 @@
-
+
-
+
+
+
+
+
+
+ file://$PROJECT_DIR$/day22/day22.go
+ 115
+
+
+
+
\ No newline at end of file
diff --git a/day22/day22.go b/day22/day22.go
new file mode 100644
index 0000000..98ff758
--- /dev/null
+++ b/day22/day22.go
@@ -0,0 +1,180 @@
+package main
+
+import (
+ "AoC2020/helper"
+ "fmt"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+type Player struct {
+ deck []int
+ previousDecks [][]int
+}
+
+type Game struct {
+ players [2]Player
+ winner int
+}
+
+var lineBreak = "\n"
+
+func main() {
+ game := Game{}
+ args := os.Args[1:]
+ input, err := helper.GetFile(args[0])
+ if err != nil {
+ fmt.Println(err)
+ }
+ playerInput := strings.Split(input, lineBreak+lineBreak)
+ player1 := parsePlayer(playerInput[0])
+ player2 := parsePlayer(playerInput[1])
+ game.players[0] = player1
+ game.players[1] = player2
+ for game.winner == 0 {
+ game = game.runRoundRecursive()
+ fmt.Println(game.players[0])
+ fmt.Println(game.players[1])
+ }
+ fmt.Println(game.winner)
+ fmt.Println(game.players[game.winner-1].deck)
+ fmt.Println(game.caculateWinnerScore())
+}
+
+func parsePlayer(input string) Player {
+ var player = Player{}
+ playerInput := strings.Split(input, lineBreak)
+ for _, val := range playerInput[1:] {
+ number, _ := strconv.Atoi(val)
+ player.deck = append(player.deck, number)
+ }
+ return player
+}
+
+func (g Game) runRound() Game {
+ g = g.saveCurrentDeck()
+ var cardP0 int
+ var cardP1 int
+ g.players[0], cardP0 = g.players[0].drawCard()
+ g.players[1], cardP1 = g.players[1].drawCard()
+ winnerCards := []int{cardP0, cardP1}
+ sort.Sort(sort.Reverse(sort.IntSlice(winnerCards)))
+ if cardP0 > cardP1 {
+ g.players[0] = g.players[0].addToDeck(winnerCards)
+ }
+ if cardP1 > cardP0 {
+ g.players[1] = g.players[1].addToDeck(winnerCards)
+ }
+ if len(g.players[0].deck) == 0 {
+ g.winner = 2
+ }
+ if len(g.players[1].deck) == 0 {
+ g.winner = 1
+ }
+ return g
+}
+
+func (g Game) caculateWinnerScore() int {
+ winnerDeck := g.players[g.winner-1].deck
+ return calculateScoreForDeck(winnerDeck)
+}
+
+func calculateScoreForDeck(deck []int) int {
+ deckLen := len(deck)
+ sum := 0
+ for i := 0; i < deckLen; i++ {
+ sum += deck[i] * (deckLen - i)
+ }
+ return sum
+}
+
+func (g Game) saveCurrentDeck() Game {
+ for i, _ := range g.players {
+ g.players[i] = g.players[i].saveCurrentDeck()
+ }
+ return g
+}
+
+func (g Game) runRoundRecursive() Game {
+ p1 := g.players[0]
+ p2 := g.players[1]
+ for i, _ := range p1.previousDecks {
+ if helper.Equal(p1.previousDecks[i], p1.deck) && helper.Equal(p2.previousDecks[i], p2.deck) {
+ g.winner = 1
+ return g
+ }
+ }
+ var roundWinner int
+ p1 = p1.saveCurrentDeck()
+ p2 = p2.saveCurrentDeck()
+ var cardP1 int
+ var cardP2 int
+ p1, cardP1 = p1.drawCard()
+ p2, cardP2 = p2.drawCard()
+ if len(p1.deck) >= cardP1 && len(p2.deck) >= cardP2 {
+ var newGame Game
+ var newPlayer1 Player
+ var newPlayer2 Player
+ newPlayer1.deck = make([]int, cardP1)
+ newPlayer2.deck = make([]int, cardP2)
+ copy(newPlayer1.deck, p1.deck[:cardP1])
+ copy(newPlayer2.deck, p2.deck[:cardP2])
+ newGame.players = [2]Player{newPlayer1, newPlayer2}
+ roundWinner = newGame.runRecursive().winner
+ } else {
+ if cardP1 > cardP2 {
+ roundWinner = 1
+ }
+ if cardP2 > cardP1 {
+ roundWinner = 2
+ }
+ }
+ if roundWinner == 1 {
+ p1 = p1.addToDeck([]int{cardP1, cardP2})
+ }
+ if roundWinner == 2 {
+ p2 = p2.addToDeck([]int{cardP2, cardP1})
+ }
+ if len(p1.deck) == 0 {
+ g.winner = 2
+ }
+ if len(p2.deck) == 0 {
+ g.winner = 1
+ }
+ g.players = [2]Player{p1, p2}
+ return g
+}
+
+func (g Game) run() Game {
+ for g.winner == 0 {
+ g = g.runRound()
+ }
+ return g
+}
+
+func (g Game) runRecursive() Game {
+ for g.winner == 0 {
+ g = g.runRoundRecursive()
+ }
+ return g
+}
+
+func (p Player) drawCard() (Player, int) {
+ card := p.deck[0]
+ p.deck = helper.DeleteAt(p.deck, 0)
+ return p, card
+}
+
+func (p Player) saveCurrentDeck() Player {
+ copyOfDeck := make([]int, len(p.deck))
+ copy(copyOfDeck, p.deck)
+ p.previousDecks = append(p.previousDecks, copyOfDeck)
+ return p
+}
+
+func (p Player) addToDeck(cards []int) Player {
+ p.deck = append(p.deck, cards...)
+ return p
+}
diff --git a/day22/day22Input.txt b/day22/day22Input.txt
new file mode 100644
index 0000000..960bb35
--- /dev/null
+++ b/day22/day22Input.txt
@@ -0,0 +1,53 @@
+Player 1:
+26
+16
+33
+8
+5
+46
+12
+47
+39
+27
+50
+10
+34
+20
+23
+11
+43
+14
+18
+1
+48
+28
+31
+38
+41
+
+Player 2:
+45
+7
+9
+4
+15
+19
+49
+3
+36
+25
+24
+2
+21
+37
+35
+44
+29
+13
+32
+22
+17
+30
+42
+40
+6
\ No newline at end of file
diff --git a/day22/day22Test.txt b/day22/day22Test.txt
new file mode 100644
index 0000000..24d78bf
--- /dev/null
+++ b/day22/day22Test.txt
@@ -0,0 +1,13 @@
+Player 1:
+9
+2
+6
+3
+1
+
+Player 2:
+5
+8
+4
+7
+10
\ No newline at end of file
diff --git a/day22/day22Test2.txt b/day22/day22Test2.txt
new file mode 100644
index 0000000..dce7e1a
--- /dev/null
+++ b/day22/day22Test2.txt
@@ -0,0 +1,8 @@
+Player 1:
+43
+19
+
+Player 2:
+2
+29
+14
\ No newline at end of file
diff --git a/helper/helper.go b/helper/helper.go
index 0e2eee0..4767ea1 100644
--- a/helper/helper.go
+++ b/helper/helper.go
@@ -37,9 +37,9 @@ func MapToNumber(strings []string) ([]int, error) {
return numbers, nil
}
-func FindAddendsForSum (possibleAddends []int, sum int) (int, int, error) {
- var array = make([]int,len(possibleAddends))
- copy(array,possibleAddends)
+func FindAddendsForSum(possibleAddends []int, sum int) (int, int, error) {
+ var array = make([]int, len(possibleAddends))
+ copy(array, possibleAddends)
sort.Ints(array)
p1 := 0
p2 := len(array) - 1
@@ -51,10 +51,10 @@ func FindAddendsForSum (possibleAddends []int, sum int) (int, int, error) {
p2--
}
if array[p1]+array[p2] == sum {
- return array[p1] , array[p2], nil
+ return array[p1], array[p2], nil
}
}
- return 0,0,errors.New("No fitting Addends found")
+ return 0, 0, errors.New("No fitting Addends found")
}
func SliceIndex(limit int, predicate func(i int) bool) int {
@@ -64,4 +64,20 @@ func SliceIndex(limit int, predicate func(i int) bool) int {
}
}
return -1
-}
\ No newline at end of file
+}
+
+func DeleteAt(a []int, i int, ) []int {
+ return append(a[:i], a[i+1:]...)
+}
+
+func Equal(a, b []int) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i, v := range a {
+ if v != b[i] {
+ return false
+ }
+ }
+ return true
+}