78 lines
1.8 KiB
Python
78 lines
1.8 KiB
Python
from collections import defaultdict
|
|
|
|
from tools.aoc import AOCDay
|
|
from typing import Any
|
|
|
|
|
|
class Marble:
|
|
number: int
|
|
left: 'Marble'
|
|
right: 'Marble'
|
|
|
|
def __init__(self, number: int):
|
|
self.number = number
|
|
|
|
|
|
def play(players: int, marbles: int):
|
|
current = Marble(0)
|
|
current.left = current
|
|
current.right = current
|
|
|
|
scores = defaultdict(int)
|
|
|
|
next_num = 1
|
|
player = 0
|
|
|
|
while next_num <= marbles:
|
|
this_marble = Marble(next_num)
|
|
if next_num % 23 == 0:
|
|
scores[player] = scores[player] + this_marble.number
|
|
for _ in range(7):
|
|
current = current.left
|
|
scores[player] = scores[player] + current.number
|
|
current.left.right = current.right
|
|
current.right.left = current.left
|
|
current = current.right
|
|
else:
|
|
current = current.right
|
|
this_marble.left = current
|
|
this_marble.right = current.right
|
|
current.right.left = this_marble
|
|
current.right = this_marble
|
|
current = this_marble
|
|
|
|
player = (player + 1) % players
|
|
next_num += 1
|
|
|
|
return max(scores.values())
|
|
|
|
|
|
class Day(AOCDay):
|
|
inputs = [
|
|
[
|
|
(8317, "input9_test1"),
|
|
(146373, "input9_test2"),
|
|
(412959, "input9"),
|
|
],
|
|
[
|
|
(3333662986, "input9"),
|
|
]
|
|
]
|
|
|
|
def parse_input(self) -> (int, int):
|
|
parts = self.getInput().split(" ")
|
|
return int(parts[0]), int(parts[6])
|
|
|
|
def part1(self) -> Any:
|
|
return play(*self.parse_input())
|
|
|
|
def part2(self) -> Any:
|
|
players, marbles = self.parse_input()
|
|
marbles *= 100
|
|
return play(players, marbles)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2018, 9)
|
|
day.run(verbose=True)
|