Skip to content

Commit aa6f8ad

Browse files
committed
Improved performance of 2020-22
1 parent c642664 commit aa6f8ad

File tree

2 files changed

+200
-49
lines changed

2 files changed

+200
-49
lines changed

2020/22-Crab Combat.py

Lines changed: 33 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -90,71 +90,55 @@ def words(s: str):
9090

9191

9292
# -------------------------------- Actual code execution ----------------------------- #
93+
def find_winner(cards, recursive):
94+
previous_decks = []
95+
96+
while cards[0] and cards[1]:
97+
# #print ('before', cards)
98+
if cards in previous_decks:
99+
return (0, None)
100+
previous_decks.append([cards[i].copy() for i in (0, 1)])
101+
102+
cards_played = [cards[i].pop(0) for i in (0, 1)]
103+
104+
if (
105+
recursive
106+
and cards_played[0] <= len(cards[0])
107+
and cards_played[1] <= len(cards[1])
108+
):
109+
# #print ('subgame')
110+
winner, _ = find_winner([cards[i][: cards_played[i]] for i in (0, 1)], True)
111+
# #print ('subgame won by', winner)
93112

94-
if part_to_test == 1:
95-
players = puzzle_input.split("\n\n")
96-
cards = [ints(player) for i, player in enumerate(players)]
97-
cards[0].pop(0)
98-
cards[1].pop(0)
99-
100-
while len(cards[0]) != 0 and len(cards[1]) != 0:
101-
if cards[0][0] >= cards[1][0]:
102-
cards[0].append(cards[0].pop(0))
103-
cards[0].append(cards[1].pop(0))
104113
else:
105-
cards[1].append(cards[1].pop(0))
106-
cards[1].append(cards[0].pop(0))
107-
108-
winner = cards[0] + cards[1]
109-
110-
score = sum([card * (len(winner) - i) for i, card in enumerate(winner)])
111-
112-
puzzle_actual_result = score
114+
winner = cards_played[0] < cards_played[1]
113115

116+
cards[winner].append(cards_played[winner])
117+
cards[winner].append(cards_played[1 - winner])
114118

115-
else:
116-
117-
def find_winner(cards):
118-
previous_decks = []
119+
winner = [i for i in (0, 1) if cards[i] != []][0]
119120

120-
while len(cards[0]) != 0 and len(cards[1]) != 0:
121-
# #print ('before', cards)
122-
if cards in previous_decks:
123-
return (0, 0)
124-
previous_decks.append(copy.deepcopy(cards))
121+
score = sum(card * (len(cards[winner]) - i) for i, card in enumerate(cards[winner]))
125122

126-
if cards[0][0] < len(cards[0]) and cards[1][0] < len(cards[1]):
127-
# #print ('subgame')
128-
winner, score = find_winner(
129-
[cards[0][1 : cards[0][0] + 1], cards[1][1 : cards[1][0] + 1]]
130-
)
131-
# #print ('subgame won by', winner)
132-
cards[winner].append(cards[winner].pop(0))
133-
cards[winner].append(cards[1 - winner].pop(0))
123+
return (winner, score)
134124

135-
elif cards[0][0] >= cards[1][0]:
136-
cards[0].append(cards[0].pop(0))
137-
cards[0].append(cards[1].pop(0))
138-
else:
139-
cards[1].append(cards[1].pop(0))
140-
cards[1].append(cards[0].pop(0))
141125

142-
winner = [i for i in (0, 1) if cards[i] != []][0]
126+
if part_to_test == 1:
127+
players = puzzle_input.split("\n\n")
128+
cards = [ints(player) for i, player in enumerate(players)]
129+
cards[0].pop(0)
130+
cards[1].pop(0)
143131

144-
score = sum(
145-
[card * (len(cards[winner]) - i) for i, card in enumerate(cards[winner])]
146-
)
132+
puzzle_actual_result = find_winner(cards, False)[1]
147133

148-
return (winner, score)
149134

135+
else:
150136
players = puzzle_input.split("\n\n")
151137
cards = [ints(player) for i, player in enumerate(players)]
152138
cards[0].pop(0)
153139
cards[1].pop(0)
154140

155-
# #print (find_winner(cards))
156-
157-
puzzle_actual_result = find_winner(cards)[1]
141+
puzzle_actual_result = find_winner(cards, True)[1]
158142

159143

160144
# -------------------------------- Outputs / results --------------------------------- #

2020/22-Crab Combat.v1.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os, grid, graph, copy, dot, assembly, re, itertools
3+
from collections import Counter, deque, defaultdict
4+
5+
from compass import *
6+
7+
8+
# This functions come from https://github.com/mcpower/adventofcode - Thanks!
9+
def lmap(func, *iterables):
10+
return list(map(func, *iterables))
11+
12+
13+
def ints(s: str):
14+
return lmap(int, re.findall(r"-?\d+", s)) # thanks mserrano!
15+
16+
17+
def positive_ints(s: str):
18+
return lmap(int, re.findall(r"\d+", s)) # thanks mserrano!
19+
20+
21+
def floats(s: str):
22+
return lmap(float, re.findall(r"-?\d+(?:\.\d+)?", s))
23+
24+
25+
def positive_floats(s: str):
26+
return lmap(float, re.findall(r"\d+(?:\.\d+)?", s))
27+
28+
29+
def words(s: str):
30+
return re.findall(r"[a-zA-Z]+", s)
31+
32+
33+
test_data = {}
34+
35+
test = 1
36+
test_data[test] = {
37+
"input": """Player 1:
38+
9
39+
2
40+
6
41+
3
42+
1
43+
44+
Player 2:
45+
5
46+
8
47+
4
48+
7
49+
10""",
50+
"expected": ["306", "291"],
51+
}
52+
53+
test += 1
54+
test_data[test] = {
55+
"input": """Player 1:
56+
43
57+
19
58+
59+
Player 2:
60+
2
61+
29
62+
14
63+
64+
""",
65+
"expected": ["Unknown", "1 wins"],
66+
}
67+
68+
test = "real"
69+
input_file = os.path.join(
70+
os.path.dirname(__file__),
71+
"Inputs",
72+
os.path.basename(__file__).replace(".py", ".txt"),
73+
)
74+
test_data[test] = {
75+
"input": open(input_file, "r+").read(),
76+
"expected": ["30197", "34031"],
77+
}
78+
79+
80+
# -------------------------------- Control program execution ------------------------- #
81+
82+
case_to_test = "real"
83+
part_to_test = 2
84+
85+
# -------------------------------- Initialize some variables ------------------------- #
86+
87+
puzzle_input = test_data[case_to_test]["input"]
88+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
89+
puzzle_actual_result = "Unknown"
90+
91+
92+
# -------------------------------- Actual code execution ----------------------------- #
93+
94+
if part_to_test == 1:
95+
players = puzzle_input.split("\n\n")
96+
cards = [ints(player) for i, player in enumerate(players)]
97+
cards[0].pop(0)
98+
cards[1].pop(0)
99+
100+
while len(cards[0]) != 0 and len(cards[1]) != 0:
101+
if cards[0][0] >= cards[1][0]:
102+
cards[0].append(cards[0].pop(0))
103+
cards[0].append(cards[1].pop(0))
104+
else:
105+
cards[1].append(cards[1].pop(0))
106+
cards[1].append(cards[0].pop(0))
107+
108+
winner = cards[0] + cards[1]
109+
110+
score = sum([card * (len(winner) - i) for i, card in enumerate(winner)])
111+
112+
puzzle_actual_result = score
113+
114+
115+
else:
116+
117+
def find_winner(cards):
118+
previous_decks = []
119+
120+
while len(cards[0]) != 0 and len(cards[1]) != 0:
121+
# #print ('before', cards)
122+
if cards in previous_decks:
123+
return (0, 0)
124+
previous_decks.append(copy.deepcopy(cards))
125+
126+
if cards[0][0] < len(cards[0]) and cards[1][0] < len(cards[1]):
127+
# #print ('subgame')
128+
winner, score = find_winner(
129+
[cards[0][1 : cards[0][0] + 1], cards[1][1 : cards[1][0] + 1]]
130+
)
131+
# #print ('subgame won by', winner)
132+
cards[winner].append(cards[winner].pop(0))
133+
cards[winner].append(cards[1 - winner].pop(0))
134+
135+
elif cards[0][0] >= cards[1][0]:
136+
cards[0].append(cards[0].pop(0))
137+
cards[0].append(cards[1].pop(0))
138+
else:
139+
cards[1].append(cards[1].pop(0))
140+
cards[1].append(cards[0].pop(0))
141+
142+
winner = [i for i in (0, 1) if cards[i] != []][0]
143+
144+
score = sum(
145+
[card * (len(cards[winner]) - i) for i, card in enumerate(cards[winner])]
146+
)
147+
148+
return (winner, score)
149+
150+
players = puzzle_input.split("\n\n")
151+
cards = [ints(player) for i, player in enumerate(players)]
152+
cards[0].pop(0)
153+
cards[1].pop(0)
154+
155+
# #print (find_winner(cards))
156+
157+
puzzle_actual_result = find_winner(cards)[1]
158+
159+
160+
# -------------------------------- Outputs / results --------------------------------- #
161+
162+
print("Case :", case_to_test, "- Part", part_to_test)
163+
print("Expected result : " + str(puzzle_expected_result))
164+
print("Actual result : " + str(puzzle_actual_result))
165+
# Date created: 2020-12-22 06:31:42.000598
166+
# Part 1: 2020-12-22 06:38:55
167+
# Part 2: 2020-12-22 07:01:53

0 commit comments

Comments
 (0)