Browse Source

Day22

master
Karl Spickermann 1 year ago
parent
commit
5dd123ea97
  1. 73
      .idea/workspace.xml
  2. 180
      day22/day22.go
  3. 53
      day22/day22Input.txt
  4. 13
      day22/day22Test.txt
  5. 8
      day22/day22Test2.txt
  6. 28
      helper/helper.go

73
.idea/workspace.xml

@ -11,8 +11,11 @@
</component>
<component name="ChangeListManager">
<list default="true" id="400bdf61-8921-41d3-8f98-a0a1b0877f46" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/day22/day22.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/day22/day22Test.txt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/day22/day22Test2.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/day20/day20.go" beforeDir="false" afterPath="$PROJECT_DIR$/day20/day20.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/helper/helper.go" beforeDir="false" afterPath="$PROJECT_DIR$/helper/helper.go" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -53,7 +56,7 @@
<recent name="C:\Users\karls\go\src\AoC2020" />
</key>
</component>
<component name="RunManager" selected="Go Build.go build day20.go">
<component name="RunManager" selected="Go Build.go build day22.go">
<configuration name="go build day10.go" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
<module name="AoC2020" />
<working_directory value="$PROJECT_DIR$/day10" />
@ -184,6 +187,16 @@
<directory value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
<configuration name="go build day22.go" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
<module name="AoC2020" />
<working_directory value="$PROJECT_DIR$/day22" />
<parameters value="day22Input.txt" />
<kind value="FILE" />
<filePath value="$PROJECT_DIR$/day22/day22.go" />
<package value="AoC2020" />
<directory value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
<configuration name="go build day2.go" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
<module name="AoC2020" />
<working_directory value="$PROJECT_DIR$/day2" />
@ -287,6 +300,7 @@
<item itemvalue="Go Build.go build day19.go" />
<item itemvalue="Go Build.go build day17.go" />
<item itemvalue="Go Build.go build day20.go" />
<item itemvalue="Go Build.go build day22.go" />
</list>
<recent_temporary>
<list>
@ -311,39 +325,59 @@
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="WindowStateProjectService">
<state x="351" y="0" width="1092" height="1040" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1608485205303">
<state x="351" y="0" width="1092" height="1040" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1608658619075">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="-1472" y="103" key="#com.intellij.execution.impl.EditConfigurationsDialog/-1920.0.1920.1040/0.0.1920.1040@-1920.0.1920.1040" timestamp="1607019292652" />
<state x="351" y="0" width="1092" height="1040" key="#com.intellij.execution.impl.EditConfigurationsDialog/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608485205303" />
<state x="351" y="0" width="1092" height="1040" key="#com.intellij.execution.impl.EditConfigurationsDialog/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658619075" />
<state x="661" y="322" key="#com.intellij.fileTypes.FileTypeChooser" timestamp="1606836882379">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="661" y="322" key="#com.intellij.fileTypes.FileTypeChooser/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1606836882379" />
<state width="546" height="466" key="DebuggerActiveHint" timestamp="1608656816732">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="546" height="466" key="DebuggerActiveHint/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608656816732" />
<state x="739" y="287" key="FileChooserDialogImpl" timestamp="1607278759015">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="739" y="287" key="FileChooserDialogImpl/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1607278759015" />
<state width="1170" height="347" key="GridCell.Tab.0.bottom" timestamp="1608495597577">
<state width="1164" height="235" key="GridCell.Tab.0.bottom" timestamp="1608658595696">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="386" key="GridCell.Tab.0.bottom/-1920.0.1920.1040/0.0.1920.1040@-1920.0.1920.1040" timestamp="1607708629475" />
<state width="1170" height="347" key="GridCell.Tab.0.bottom/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608495597577" />
<state width="1170" height="347" key="GridCell.Tab.0.center" timestamp="1608495597577">
<state width="1164" height="235" key="GridCell.Tab.0.bottom/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658595696" />
<state width="1164" height="235" key="GridCell.Tab.0.center" timestamp="1608658595696">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="386" key="GridCell.Tab.0.center/-1920.0.1920.1040/0.0.1920.1040@-1920.0.1920.1040" timestamp="1607708629474" />
<state width="1170" height="347" key="GridCell.Tab.0.center/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608495597577" />
<state width="1170" height="347" key="GridCell.Tab.0.left" timestamp="1608495597577">
<state width="1164" height="235" key="GridCell.Tab.0.center/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658595696" />
<state width="1164" height="235" key="GridCell.Tab.0.left" timestamp="1608658595696">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="386" key="GridCell.Tab.0.left/-1920.0.1920.1040/0.0.1920.1040@-1920.0.1920.1040" timestamp="1607708629474" />
<state width="1170" height="347" key="GridCell.Tab.0.left/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608495597577" />
<state width="1170" height="347" key="GridCell.Tab.0.right" timestamp="1608495597577">
<state width="1164" height="235" key="GridCell.Tab.0.left/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658595696" />
<state width="1164" height="235" key="GridCell.Tab.0.right" timestamp="1608658595696">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="386" key="GridCell.Tab.0.right/-1920.0.1920.1040/0.0.1920.1040@-1920.0.1920.1040" timestamp="1607708629475" />
<state width="1170" height="347" key="GridCell.Tab.0.right/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608495597577" />
<state width="1164" height="235" key="GridCell.Tab.0.right/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658595696" />
<state width="938" height="425" key="GridCell.Tab.1.bottom" timestamp="1608658103907">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="938" height="425" key="GridCell.Tab.1.bottom/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658103907" />
<state width="938" height="425" key="GridCell.Tab.1.center" timestamp="1608658103906">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="938" height="425" key="GridCell.Tab.1.center/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658103906" />
<state width="938" height="425" key="GridCell.Tab.1.left" timestamp="1608658103906">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="938" height="425" key="GridCell.Tab.1.left/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658103906" />
<state width="938" height="425" key="GridCell.Tab.1.right" timestamp="1608658103906">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="938" height="425" key="GridCell.Tab.1.right/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608658103906" />
<state x="782" y="240" key="RollbackChangesDialog" timestamp="1608474837005">
<screen x="0" y="0" width="1920" height="1040" />
</state>
@ -364,9 +398,20 @@
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="593" y="141" width="585" height="801" key="find.popup/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608483030515" />
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1608484725602">
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1608654442412">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608484725602" />
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup/-1920.0.1920.1040/0.0.1920.1040@0.0.1920.1040" timestamp="1608654442412" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/day22/day22.go</url>
<line>115</line>
<option name="timeStamp" value="20" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

180
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
}

53
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

13
day22/day22Test.txt

@ -0,0 +1,13 @@
Player 1:
9
2
6
3
1
Player 2:
5
8
4
7
10

8
day22/day22Test2.txt

@ -0,0 +1,8 @@
Player 1:
43
19
Player 2:
2
29
14

28
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
}
}
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
}

Loading…
Cancel
Save