|
|
|
import os
|
|
|
|
from typing import List, Tuple
|
|
|
|
|
|
|
|
|
|
|
|
class RPS:
|
|
|
|
WIN_SYM = "Z"
|
|
|
|
DRAW_SYM = "Y"
|
|
|
|
LOSS_SYM = "X"
|
|
|
|
|
|
|
|
ROCK = "R"
|
|
|
|
PAPER = "P"
|
|
|
|
SCISSOR = "S"
|
|
|
|
|
|
|
|
ROCK_SCORE = 1
|
|
|
|
PAPER_SCORE = 2
|
|
|
|
SCISSOR_SCORE = 3
|
|
|
|
|
|
|
|
WIN_SCORE = 6
|
|
|
|
DRAW_SCORE = 3
|
|
|
|
LOSS_SCORE = 0
|
|
|
|
|
|
|
|
RPS_SYM_TO_SHAPE = {
|
|
|
|
"A": ROCK,
|
|
|
|
"X": ROCK,
|
|
|
|
|
|
|
|
"B": PAPER,
|
|
|
|
"Y": PAPER,
|
|
|
|
|
|
|
|
"C": SCISSOR,
|
|
|
|
"Z": SCISSOR
|
|
|
|
}
|
|
|
|
|
|
|
|
RPS_SHAPE_TO_SCORE = {
|
|
|
|
ROCK: ROCK_SCORE,
|
|
|
|
PAPER: PAPER_SCORE,
|
|
|
|
SCISSOR: SCISSOR_SCORE
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class RockPaperScissorGuide:
|
|
|
|
"""
|
|
|
|
Day 2 - Rock Paper Scissors
|
|
|
|
|
|
|
|
The Elves begin to set up camp on the beach. To decide whose tent gets to be closest to the snack storage,
|
|
|
|
a giant Rock Paper Scissors tournament is already in progress.
|
|
|
|
|
|
|
|
One Elf gives you an encrypted strategy guide (your puzzle input) that they say will be sure to help you win.
|
|
|
|
The first column is what your opponent is going to play: A for Rock, B for Paper, and C for Scissors.
|
|
|
|
The second column, you reason, must be what you should play in response: X for Rock, Y for Paper,
|
|
|
|
and Z for Scissors. Winning every time would be suspicious, so the responses must have been carefully chosen.
|
|
|
|
|
|
|
|
The score for a single round is the score for the shape you selected (1 for Rock, 2 for Paper, and 3 for Scissors)
|
|
|
|
plus the score for the outcome of the round (0 if you lost, 3 if the round was a draw, and 6 if you won).
|
|
|
|
|
|
|
|
(Part 2 only)
|
|
|
|
The second column says how the round needs to end: X means you need to lose,
|
|
|
|
Y means you need to end the round in a draw, and Z means you need to win.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, path: str):
|
|
|
|
if not os.path.isfile(path):
|
|
|
|
raise FileNotFoundError(f"File was not found or isn't a file: {path}")
|
|
|
|
|
|
|
|
self.file_path = path
|
|
|
|
|
|
|
|
def parse_file_v1(self) -> List[Tuple[str, str]]:
|
|
|
|
strategy_guide = []
|
|
|
|
with open(self.file_path, "r") as file:
|
|
|
|
for line in file:
|
|
|
|
line = line.replace("\n", "")
|
|
|
|
a, b = line.split(" ")
|
|
|
|
strategy_guide.append((RPS.RPS_SYM_TO_SHAPE[a], RPS.RPS_SYM_TO_SHAPE[b]))
|
|
|
|
|
|
|
|
return strategy_guide
|
|
|
|
|
|
|
|
def parse_file(self) -> List[Tuple[str, str]]:
|
|
|
|
strategy_guide = []
|
|
|
|
with open(self.file_path, "r") as file:
|
|
|
|
for line in file:
|
|
|
|
line = line.replace("\n", "")
|
|
|
|
a, b = line.split(" ")
|
|
|
|
|
|
|
|
a = RPS.RPS_SYM_TO_SHAPE[a]
|
|
|
|
|
|
|
|
answer = None
|
|
|
|
|
|
|
|
if b == RPS.WIN_SYM:
|
|
|
|
if a == RPS.ROCK:
|
|
|
|
answer = RPS.PAPER
|
|
|
|
elif a == RPS.PAPER:
|
|
|
|
answer = RPS.SCISSOR
|
|
|
|
elif a == RPS.SCISSOR:
|
|
|
|
answer = RPS.ROCK
|
|
|
|
elif b == RPS.DRAW_SYM:
|
|
|
|
answer = a
|
|
|
|
elif b == RPS.LOSS_SYM:
|
|
|
|
if a == RPS.ROCK:
|
|
|
|
answer = RPS.SCISSOR
|
|
|
|
elif a == RPS.PAPER:
|
|
|
|
answer = RPS.ROCK
|
|
|
|
elif a == RPS.SCISSOR:
|
|
|
|
answer = RPS.PAPER
|
|
|
|
|
|
|
|
if answer is None:
|
|
|
|
raise ValueError("Something went wrong with answer determination!")
|
|
|
|
|
|
|
|
strategy_guide.append((a, answer))
|
|
|
|
|
|
|
|
return strategy_guide
|