Skip to content

Commit 16b180f

Browse files
days 22, 23, and 24
1 parent 20db6da commit 16b180f

File tree

11 files changed

+938
-7
lines changed

11 files changed

+938
-7
lines changed

β€Žday22/day22.go

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package day22
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/alokmenghrajani/adventofcode2020/utils"
8+
)
9+
10+
func Part1(input string) int {
11+
var player1 []int
12+
var player2 []int
13+
14+
cards := strings.Split(input, "\n\n")
15+
for _, line := range strings.Split(cards[0], "\n")[1:] {
16+
player1 = append(player1, utils.MustAtoi(line))
17+
}
18+
for _, line := range strings.Split(cards[1], "\n")[1:] {
19+
player2 = append(player2, utils.MustAtoi(line))
20+
}
21+
22+
winner := combatPart1(player1, player2)
23+
24+
r := 0
25+
f := 1
26+
for i := len(winner) - 1; i >= 0; i-- {
27+
r = r + winner[i]*f
28+
f++
29+
}
30+
return r
31+
}
32+
33+
func combatPart1(player1, player2 []int) []int {
34+
for len(player1) > 0 && len(player2) > 0 {
35+
top1 := player1[0]
36+
player1 = player1[1:]
37+
38+
top2 := player2[0]
39+
player2 = player2[1:]
40+
41+
if top1 > top2 {
42+
player1 = append(player1, top1)
43+
player1 = append(player1, top2)
44+
} else {
45+
player2 = append(player2, top2)
46+
player2 = append(player2, top1)
47+
}
48+
}
49+
if len(player1) > 0 {
50+
return player1
51+
}
52+
if len(player2) > 0 {
53+
return player2
54+
}
55+
panic("invalid state")
56+
}
57+
58+
func Part2(input string) int {
59+
var player1 []int
60+
var player2 []int
61+
62+
cards := strings.Split(input, "\n\n")
63+
for _, line := range strings.Split(cards[0], "\n")[1:] {
64+
player1 = append(player1, utils.MustAtoi(line))
65+
}
66+
for _, line := range strings.Split(cards[1], "\n")[1:] {
67+
player2 = append(player2, utils.MustAtoi(line))
68+
}
69+
70+
_, winner := combatPart2(player1, player2)
71+
72+
r := 0
73+
f := 1
74+
for i := len(winner) - 1; i >= 0; i-- {
75+
r = r + winner[i]*f
76+
f++
77+
}
78+
return r
79+
}
80+
81+
func intsToStrings(a []int) []string {
82+
var r []string
83+
for _, n := range a {
84+
r = append(r, fmt.Sprintf("%d", n))
85+
}
86+
return r
87+
}
88+
89+
func combatPart2(player1, player2 []int) (bool, []int) {
90+
memoize := map[string]bool{}
91+
for len(player1) > 0 && len(player2) > 0 {
92+
t := strings.Join(intsToStrings(player1), ",")
93+
if memoize[t] {
94+
return true, player1
95+
}
96+
memoize[t] = true
97+
98+
t = strings.Join(intsToStrings(player2), ",")
99+
if memoize[t] {
100+
return true, player1
101+
}
102+
memoize[t] = true
103+
104+
top1 := player1[0]
105+
player1 = player1[1:]
106+
107+
top2 := player2[0]
108+
player2 = player2[1:]
109+
110+
var r bool
111+
if len(player1) >= top1 && len(player2) >= top2 {
112+
copyPlayer1 := make([]int, top1)
113+
copy(copyPlayer1, player1)
114+
115+
copyPlayer2 := make([]int, top2)
116+
copy(copyPlayer2, player2)
117+
118+
r, _ = combatPart2(copyPlayer1, copyPlayer2)
119+
} else {
120+
r = top1 > top2
121+
}
122+
if r {
123+
player1 = append(player1, top1)
124+
player1 = append(player1, top2)
125+
} else {
126+
player2 = append(player2, top2)
127+
player2 = append(player2, top1)
128+
}
129+
}
130+
if len(player1) > 0 {
131+
return true, player1
132+
}
133+
if len(player2) > 0 {
134+
return false, player2
135+
}
136+
panic("invalid state")
137+
}

β€Žday22/day22_test.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package day22
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestPart1(t *testing.T) {
10+
r := Part1(`Player 1:
11+
9
12+
2
13+
6
14+
3
15+
1
16+
17+
Player 2:
18+
5
19+
8
20+
4
21+
7
22+
10`)
23+
require.Equal(t, 306, r)
24+
}
25+
26+
func TestPart2(t *testing.T) {
27+
r := Part2(`Player 1:
28+
9
29+
2
30+
6
31+
3
32+
1
33+
34+
Player 2:
35+
5
36+
8
37+
4
38+
7
39+
10`)
40+
require.Equal(t, 291, r)
41+
}

β€Žday22/input.txt

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
Player 1:
2+
2
3+
31
4+
14
5+
45
6+
33
7+
18
8+
29
9+
36
10+
44
11+
47
12+
38
13+
6
14+
9
15+
5
16+
48
17+
17
18+
50
19+
41
20+
4
21+
21
22+
42
23+
23
24+
25
25+
28
26+
3
27+
28+
Player 2:
29+
26
30+
16
31+
27
32+
12
33+
49
34+
32
35+
19
36+
46
37+
37
38+
15
39+
10
40+
30
41+
11
42+
24
43+
1
44+
40
45+
7
46+
8
47+
43
48+
34
49+
20
50+
35
51+
22
52+
39
53+
13

β€Žday23/day23.go

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package day23
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/alokmenghrajani/adventofcode2020/utils"
8+
)
9+
10+
type cup struct {
11+
id int
12+
next *cup
13+
}
14+
15+
func Part1(input string) string {
16+
var first *cup
17+
var prev *cup
18+
cups := map[int]*cup{}
19+
max := 0
20+
for _, n := range strings.Split(input, "") {
21+
curr := &cup{
22+
id: utils.MustAtoi(n),
23+
}
24+
max = utils.IntMax(max, curr.id)
25+
cups[curr.id] = curr
26+
if first == nil {
27+
first = curr
28+
} else {
29+
prev.next = curr
30+
}
31+
prev = curr
32+
}
33+
prev.next = first
34+
35+
curr := first
36+
for t := 0; t < 100; t++ {
37+
// remove 3 cups
38+
cup1 := curr.next
39+
cup2 := cup1.next
40+
cup3 := cup2.next
41+
curr.next = cup3.next
42+
43+
n := curr.id
44+
for {
45+
n--
46+
if n == 0 {
47+
n = max
48+
}
49+
if n != cup1.id && n != cup2.id && n != cup3.id {
50+
break
51+
}
52+
}
53+
54+
dest := cups[n]
55+
cup3.next = dest.next
56+
dest.next = cup1
57+
curr = curr.next
58+
}
59+
60+
r := ""
61+
curr = cups[1].next
62+
for curr != cups[1] {
63+
r = fmt.Sprintf("%s%d", r, curr.id)
64+
curr = curr.next
65+
}
66+
67+
return r
68+
}
69+
70+
func Part2(input string) int {
71+
var first *cup
72+
var prev *cup
73+
cups := map[int]*cup{}
74+
max := 0
75+
for _, n := range strings.Split(input, "") {
76+
curr := &cup{
77+
id: utils.MustAtoi(n),
78+
}
79+
max = utils.IntMax(max, curr.id)
80+
cups[curr.id] = curr
81+
if first == nil {
82+
first = curr
83+
} else {
84+
prev.next = curr
85+
}
86+
prev = curr
87+
}
88+
for len(cups) < 1_000_000 {
89+
curr := &cup{
90+
id: max + 1,
91+
}
92+
max = utils.IntMax(max, curr.id)
93+
cups[curr.id] = curr
94+
prev.next = curr
95+
prev = curr
96+
}
97+
prev.next = first
98+
99+
curr := first
100+
for t := 0; t < 10_000_000; t++ {
101+
// remove 3 cups
102+
cup1 := curr.next
103+
cup2 := cup1.next
104+
cup3 := cup2.next
105+
curr.next = cup3.next
106+
107+
n := curr.id
108+
for {
109+
n--
110+
if n == 0 {
111+
n = max
112+
}
113+
if n != cup1.id && n != cup2.id && n != cup3.id {
114+
break
115+
}
116+
}
117+
118+
dest := cups[n]
119+
cup3.next = dest.next
120+
dest.next = cup1
121+
curr = curr.next
122+
}
123+
return cups[1].next.id * cups[1].next.next.id
124+
}

β€Žday23/day23_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package day23
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestPart1(t *testing.T) {
10+
r := Part1(`389125467`)
11+
require.Equal(t, "67384529", r)
12+
}
13+
14+
func TestPart2(t *testing.T) {
15+
r := Part2(`389125467`)
16+
require.Equal(t, 149245887792, r)
17+
}

β€Žday23/input.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
583976241

0 commit comments

Comments
Β (0)