Compare commits

...

2 Commits

Author SHA1 Message Date
696dbfc739 Solve 2020/23 2020-12-23 17:27:16 +01:00
f5df4c2e4a Solve 2020/22 2020-12-23 14:53:08 +01:00
7 changed files with 333 additions and 0 deletions

13
2020/22/example Normal file
View File

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

9
2020/22/example2 Normal file
View File

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

53
2020/22/input Normal file
View File

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

38
2020/22/solution1.py Normal file
View File

@ -0,0 +1,38 @@
from collections import deque
p1 = deque()
p2 = deque()
with open('input', 'r') as f:
f.readline() # player 1
while (line := f.readline()) and line != '\n':
p1.append(int(line))
f.readline() # player 2
while (line := f.readline()) and line != '\n':
p2.append(int(line))
print(p1)
print(p2)
while len(p1) and len(p2):
a = p1.popleft()
b = p2.popleft()
winner = p1 if a > b else p2
winner.append(max(a, b))
winner.append(min(a, b))
print(p1)
print(p2)
winner = p1 if len(p1) else p2
i = 1
score = 0
while len(winner):
score += winner.pop() * i
i += 1
print(score)

66
2020/22/solution2.py Normal file
View File

@ -0,0 +1,66 @@
from collections import deque
p1 = deque()
p2 = deque()
with open('input', 'r') as f:
f.readline() # player 1
while (line := f.readline()) and line != '\n':
p1.append(int(line))
f.readline() # player 2
while (line := f.readline()) and line != '\n':
p2.append(int(line))
print('p1:', p1)
print('p2:', p2)
def game(p1, p2):
rounds = set()
while len(p1) and len(p2):
# prevent infinite games
round_hash = str(p1) + str(p2)
if round_hash in rounds:
return 1
rounds.add(round_hash)
a = p1.popleft()
b = p2.popleft()
# check if each player has enough cards for recursion
if len(p1) >= a and len(p2) >= b:
new_p1 = p1.copy()
new_p2 = p2.copy()
while len(new_p1) > a:
new_p1.pop()
while len(new_p2) > b:
new_p2.pop()
winner = game(new_p1, new_p2)
else:
# normal round
winner = 1 if a > b else 2
# append cards to winner
winning_player = p1 if winner == 1 else p2
winning_player.append(a if winner == 1 else b)
winning_player.append(b if winner == 1 else a)
return 1 if len(p1) else 2
game(p1, p2)
print('After game:')
print('p1:', p1)
print('p2:', p2)
winner = p1 if len(p1) else p2
i = 1
score = 0
while len(winner):
score += winner.pop() * i
i += 1
print('Score:')
print(score)

52
2020/23/solution1.py Normal file
View File

@ -0,0 +1,52 @@
"""Solution to 2020/23"""
from collections import deque
EXAMPLE = '389125467'
INPUT = '952316487'
# INPUT = EXAMPLE
MOVES = 100
def main():
all_cups = deque(sorted(INPUT))
cups = deque(INPUT)
for move in range(MOVES):
print(f'-- MOVE {move + 1} --')
while all_cups[0] != cups[0]:
all_cups.rotate()
print(f'cups: {list(cups)}')
cur = cups[0]
cups.rotate(-1)
lift = [cups.popleft(), cups.popleft(), cups.popleft()]
next_cup = cups[0]
print('pick up:', lift)
all_cups.rotate()
while all_cups[0] in lift:
all_cups.rotate()
destination = all_cups[0]
print('destination:', destination)
while cups[-1] != destination:
cups.rotate()
cups.extend(lift)
while cups[0] != next_cup:
cups.rotate()
print('-- Final:--')
print(cups)
print()
while cups[0] != '1':
cups.rotate()
cups.popleft()
print(''.join(list(cups)))
main()

102
2020/23/solution2.py Normal file
View File

@ -0,0 +1,102 @@
"""Solution to 2020/23"""
from collections import deque
EXAMPLE = '389125467'
INPUT = '952316487'
# INPUT = EXAMPLE
MOVES = 10_000_000
INPUT = list(map(int, INPUT))
INPUT = INPUT + list(range(max(INPUT) + 1, 1_000_000 + 1))
def main():
cups = CrabCups(INPUT)
print(cups)
for move in range(MOVES):
if move % 1_000_000 == 0:
print(f'-- MOVE {move} --')
cups.move()
print()
print('finished')
print(cups._nodes[1].next.value * cups._nodes[1].next.next.value)
exit()
class CrabCups:
def __init__(self, cups):
nodes = dict()
i = 0
prev = None
while i < len(cups):
node = Node(cups[i])
if prev:
node.prev = prev
prev.next = node
prev = node
nodes[cups[i]] = node
i += 1
nodes[cups[0]].prev = nodes[cups[-1]]
nodes[cups[-1]].next = nodes[cups[0]]
self._nodes = nodes
self.cur = nodes[cups[0]]
self.cup_count = len(cups)
self.last_cur = None
self.last_pick_up = None
self.last_destination = None
def move(self):
pick_up = set()
link = self.cur
self.last_cur = self.cur
self.last_pick_up = link.next
for _ in range(3):
link = link.next
pick_up.add(link.value)
# wire cur with cup after pickups
link.next.prev = self.cur
self.cur.next = link.next
# find dest
dest = self.cur.value - 1
dest = dest if dest != 0 else self.cup_count
while dest in pick_up:
dest -= 1
dest = dest if dest != 0 else self.cup_count
dest = self._nodes[dest]
self.last_dest = dest
dest.next.prev = link
link.next = dest.next
link = link.prev.prev
dest.next = link
link.prev = dest
self.cur = self.cur.next
def as_list(self, start):
cups = [start.value]
cur = start.next
while not cur is start:
cups.append(cur.value)
cur = cur.next
return cups
class Node:
next = None
prev = None
def __init__(self, val):
self.value = val
main()