From 4f502d483c297fcee465026e419a3793867e650e Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 00:26:04 +0200 Subject: [PATCH 01/34] Create solution file for part 1 --- puzzles/solutions/2022/d02/p1.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 puzzles/solutions/2022/d02/p1.py diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py new file mode 100644 index 0000000..c3bbf49 --- /dev/null +++ b/puzzles/solutions/2022/d02/p1.py @@ -0,0 +1,12 @@ +import sys + + +def get_answer(input_text: str): + raise NotImplementedError + + +if __name__ == "__main__": + try: + print(get_answer(sys.argv[1])) + except IndexError: + pass # Don't crash if no input was passed through command line arguments. From 717483cf76a050dd3e517ed32e1077c36242d9ac Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 00:39:49 +0200 Subject: [PATCH 02/34] Add function that parses the input --- puzzles/solutions/2022/d02/p1.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index c3bbf49..2c3d68f 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -1,6 +1,15 @@ import sys +def get_moves(input_text: str) -> list[tuple[str, str]]: + """ + :param input_text: puzzle input + :return: list of (opponent move, our move) couples + """ + moves = input_text.splitlines() + return [tuple(move.split()) for move in moves] + + def get_answer(input_text: str): raise NotImplementedError From f03f53981a14315abfeb193750451dc9885f7bd2 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:05:44 +0200 Subject: [PATCH 03/34] Create Python module for shapes constants --- puzzles/solutions/2022/d02/shapes.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 puzzles/solutions/2022/d02/shapes.py diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py new file mode 100644 index 0000000..1237cea --- /dev/null +++ b/puzzles/solutions/2022/d02/shapes.py @@ -0,0 +1 @@ +"""Various constants used for Rock Paper Scissors shapes and other data about them.""" From 1441ba330c8e19e9fdd09628cfecb99d2db9d754 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:09:20 +0200 Subject: [PATCH 04/34] Add constants for the shapes --- puzzles/solutions/2022/d02/shapes.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 1237cea..2548a65 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -1 +1,9 @@ """Various constants used for Rock Paper Scissors shapes and other data about them.""" + + +OUR_ROCK = "X" +OUR_PAPER = "Y" +OUR_SCISSORS = "Z" +OPPONENT_ROCK = "A" +OPPONENT_PAPER = "B" +OPPONENT_SCISSORS = "C" From 7425b50159cf79e491440d5915e75898ee67607b Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:10:28 +0200 Subject: [PATCH 05/34] Add dictionary that maps what opponent's shape is defeated by our shape --- puzzles/solutions/2022/d02/shapes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 2548a65..7e4298e 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -7,3 +7,9 @@ OPPONENT_ROCK = "A" OPPONENT_PAPER = "B" OPPONENT_SCISSORS = "C" + +OUR_TO_OPPONENT_SHAPE_DEFEAT = { + OUR_ROCK: OPPONENT_SCISSORS, + OUR_PAPER: OPPONENT_ROCK, + OUR_SCISSORS: OPPONENT_PAPER, +} From f71763daa7df7c4ab99cc1bdf0e4b3d5056c9eec Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:10:52 +0200 Subject: [PATCH 06/34] Add dictionary that maps what shapes are identical --- puzzles/solutions/2022/d02/shapes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 7e4298e..a1c0a1c 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -13,3 +13,9 @@ OUR_PAPER: OPPONENT_ROCK, OUR_SCISSORS: OPPONENT_PAPER, } + +IDENTICAL_SHAPES = { + OUR_ROCK: OPPONENT_ROCK, + OUR_PAPER: OPPONENT_PAPER, + OUR_SCISSORS: OPPONENT_SCISSORS, +} From 04504094a85ccac1ddda310a692a04858631ee0c Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:15:25 +0200 Subject: [PATCH 07/34] Add dictionary that maps shapes to their respective scores --- puzzles/solutions/2022/d02/shapes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index a1c0a1c..dcb31e6 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -19,3 +19,5 @@ OUR_PAPER: OPPONENT_PAPER, OUR_SCISSORS: OPPONENT_SCISSORS, } + +SHAPE_TO_SCORE = {OUR_ROCK: 1, OUR_PAPER: 2, OUR_SCISSORS: 3} From 74025e48a5c9a99555cfa5977f3e918dde443a42 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:21:48 +0200 Subject: [PATCH 08/34] Add function that calculates a move's score --- puzzles/solutions/2022/d02/p1.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 2c3d68f..1a26883 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -1,5 +1,7 @@ import sys +import shapes + def get_moves(input_text: str) -> list[tuple[str, str]]: """ @@ -10,6 +12,22 @@ def get_moves(input_text: str) -> list[tuple[str, str]]: return [tuple(move.split()) for move in moves] +def calculate_move_score(move: tuple[str, str]) -> int: + """ + :param move: couple of (opponent move, our move) couples + :return: total score of the move + """ + score = 0 + opponent_move, our_move = move + if shapes.OUR_TO_OPPONENT_SHAPE_DEFEAT[our_move] == opponent_move: + score += 6 + elif shapes.IDENTICAL_SHAPES[our_move] == opponent_move: + score += 3 + + score += shapes.SHAPE_TO_SCORE[our_move] + return score + + def get_answer(input_text: str): raise NotImplementedError From 0a705089ae28a71e946a83f15a0dfc1b12a092b2 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:32:23 +0200 Subject: [PATCH 09/34] Add function that calculates total score --- puzzles/solutions/2022/d02/p1.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 1a26883..fafcd42 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -29,7 +29,10 @@ def calculate_move_score(move: tuple[str, str]) -> int: def get_answer(input_text: str): - raise NotImplementedError + """Return the total score if everything goes exactly according to our strategy guide.""" + moves = get_moves(input_text) + total_score = sum(calculate_move_score(move) for move in moves) + return total_score if __name__ == "__main__": From 334cbab9cd67b9550615f84f9256330fd0c2c630 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:33:43 +0200 Subject: [PATCH 10/34] Create solution file for part 2 --- puzzles/solutions/2022/d02/p2.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 puzzles/solutions/2022/d02/p2.py diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py new file mode 100644 index 0000000..c3bbf49 --- /dev/null +++ b/puzzles/solutions/2022/d02/p2.py @@ -0,0 +1,12 @@ +import sys + + +def get_answer(input_text: str): + raise NotImplementedError + + +if __name__ == "__main__": + try: + print(get_answer(sys.argv[1])) + except IndexError: + pass # Don't crash if no input was passed through command line arguments. From 5c22100a80d58cbfc8bb8daf32d54d0a71983ba7 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:36:25 +0200 Subject: [PATCH 11/34] Add constants for letters and outcomes --- puzzles/solutions/2022/d02/p2.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index c3bbf49..64f5dd6 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -1,6 +1,11 @@ import sys +DEFEAT = "X" +DRAW = "Y" +WIN = "Z" + + def get_answer(input_text: str): raise NotImplementedError From 661570b454de4fc86ad281603fca11deddd2d76d Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:43:18 +0200 Subject: [PATCH 12/34] Add dictionary that maps what opponent's shape defeats our shape --- puzzles/solutions/2022/d02/shapes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index dcb31e6..7fecde7 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -14,6 +14,12 @@ OUR_SCISSORS: OPPONENT_PAPER, } +OPPONENT_TO_OUR_SHAPE_DEFEAT = { + OPPONENT_ROCK: OUR_SCISSORS, + OPPONENT_PAPER: OUR_ROCK, + OPPONENT_SCISSORS: OUR_PAPER, +} + IDENTICAL_SHAPES = { OUR_ROCK: OPPONENT_ROCK, OUR_PAPER: OPPONENT_PAPER, From 30d36784acc7240807c63e906f19e81dbcc0bb59 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:45:57 +0200 Subject: [PATCH 13/34] Add function that returns what shape should be played --- puzzles/solutions/2022/d02/p2.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 64f5dd6..5bd4d39 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -1,11 +1,31 @@ import sys +import shapes + DEFEAT = "X" DRAW = "Y" WIN = "Z" +def choose_shape(opponent_move: str, outcome: str) -> str: + """ + :param opponent_move: move the opponent played + :param outcome: desired outcome of the move + :return: shape to play for the desired outcome to happen + """ + if outcome == DEFEAT: + return shapes.OPPONENT_TO_OUR_SHAPE_DEFEAT[opponent_move] + if outcome == DRAW: + for our_shape, opponent_shape in shapes.IDENTICAL_SHAPES.items(): + if opponent_shape == opponent_move: + return our_shape + if outcome == WIN: + for our_shape, opponent_shape in shapes.OUR_TO_OPPONENT_SHAPE_DEFEAT.items(): + if opponent_shape == opponent_move: + return our_shape + + def get_answer(input_text: str): raise NotImplementedError From 6f652cb245f851aa4412267151efc98f24fa35b5 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 01:51:06 +0200 Subject: [PATCH 14/34] Add function that generate moves based on opponent moves and outcomes --- puzzles/solutions/2022/d02/p2.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 5bd4d39..448a746 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -26,6 +26,17 @@ def choose_shape(opponent_move: str, outcome: str) -> str: return our_shape +def generate_moves(moves_outcomes: list[tuple[str, str]]) -> list[tuple[str, str]]: + """ + :param moves_outcomes: list of (opponent move, desired outcome) couples + :return: list of (opponent move, desired move for desired outcome to happen) couples + """ + return [ + (opponent_move, choose_shape(opponent_move, outcome)) + for opponent_move, outcome in moves_outcomes + ] + + def get_answer(input_text: str): raise NotImplementedError From 76578a17a7d49b5f1ef636be22fc7e8eac8c105b Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 02:04:33 +0200 Subject: [PATCH 15/34] Add function that calculates total score --- puzzles/solutions/2022/d02/p2.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 448a746..85afde5 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -1,5 +1,6 @@ import sys +import p1 import shapes @@ -38,7 +39,11 @@ def generate_moves(moves_outcomes: list[tuple[str, str]]) -> list[tuple[str, str def get_answer(input_text: str): - raise NotImplementedError + """Return the total score if everything goes exactly according to our actual strategy guide.""" + moves_outcomes = p1.get_moves(input_text) + moves = generate_moves(moves_outcomes) + total_score = sum(p1.calculate_move_score(move) for move in moves) + return total_score if __name__ == "__main__": From 7ac5567dee9f2e462376b9c8105c636d7fe5511d Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 13:43:26 +0200 Subject: [PATCH 16/34] Return tuples instead of lists --- puzzles/solutions/2022/d02/p1.py | 4 ++-- puzzles/solutions/2022/d02/p2.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index fafcd42..012db0a 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -3,13 +3,13 @@ import shapes -def get_moves(input_text: str) -> list[tuple[str, str]]: +def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: """ :param input_text: puzzle input :return: list of (opponent move, our move) couples """ moves = input_text.splitlines() - return [tuple(move.split()) for move in moves] + return tuple(tuple(move.split()) for move in moves) def calculate_move_score(move: tuple[str, str]) -> int: diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 85afde5..68adb58 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -27,15 +27,15 @@ def choose_shape(opponent_move: str, outcome: str) -> str: return our_shape -def generate_moves(moves_outcomes: list[tuple[str, str]]) -> list[tuple[str, str]]: +def generate_moves(moves_outcomes: tuple[tuple[str, str]]) -> tuple[tuple[str, str], ...]: """ :param moves_outcomes: list of (opponent move, desired outcome) couples :return: list of (opponent move, desired move for desired outcome to happen) couples """ - return [ + return tuple( (opponent_move, choose_shape(opponent_move, outcome)) for opponent_move, outcome in moves_outcomes - ] + ) def get_answer(input_text: str): From 0bbe1de0ebd21531605e9606f4bc96bec8d52d54 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 13:48:24 +0200 Subject: [PATCH 17/34] Replace "couple" vs "pair" --- puzzles/solutions/2022/d02/p1.py | 4 ++-- puzzles/solutions/2022/d02/p2.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 012db0a..18ab103 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -6,7 +6,7 @@ def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: """ :param input_text: puzzle input - :return: list of (opponent move, our move) couples + :return: list of (opponent move, our move) pairs """ moves = input_text.splitlines() return tuple(tuple(move.split()) for move in moves) @@ -14,7 +14,7 @@ def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: def calculate_move_score(move: tuple[str, str]) -> int: """ - :param move: couple of (opponent move, our move) couples + :param move: pair of (opponent move, our move) pairs :return: total score of the move """ score = 0 diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 68adb58..273c11e 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -29,8 +29,8 @@ def choose_shape(opponent_move: str, outcome: str) -> str: def generate_moves(moves_outcomes: tuple[tuple[str, str]]) -> tuple[tuple[str, str], ...]: """ - :param moves_outcomes: list of (opponent move, desired outcome) couples - :return: list of (opponent move, desired move for desired outcome to happen) couples + :param moves_outcomes: list of (opponent move, desired outcome) pairs + :return: list of (opponent move, desired move for desired outcome to happen) pairs """ return tuple( (opponent_move, choose_shape(opponent_move, outcome)) From de7da71190eee3f11bf49152bf3a76ab07c516bb Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 13:48:43 +0200 Subject: [PATCH 18/34] Remove wrong word --- puzzles/solutions/2022/d02/p1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 18ab103..125ae85 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -14,7 +14,7 @@ def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: def calculate_move_score(move: tuple[str, str]) -> int: """ - :param move: pair of (opponent move, our move) pairs + :param move: pair of (opponent move, our move) :return: total score of the move """ score = 0 From ed1911fa06f0308ccde36cd9dd853c2b28164170 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 14:10:03 +0200 Subject: [PATCH 19/34] Remove "our" from shapes names --- puzzles/solutions/2022/d02/shapes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 7fecde7..0ecb34f 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -1,9 +1,9 @@ """Various constants used for Rock Paper Scissors shapes and other data about them.""" -OUR_ROCK = "X" -OUR_PAPER = "Y" -OUR_SCISSORS = "Z" +ROCK = "X" +PAPER = "Y" +SCISSORS = "Z" OPPONENT_ROCK = "A" OPPONENT_PAPER = "B" OPPONENT_SCISSORS = "C" From 9de1b779048ae6489f86903c30fe3284cdf276e3 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 14:21:43 +0200 Subject: [PATCH 20/34] Move identical shapes list up and update names --- puzzles/solutions/2022/d02/shapes.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 0ecb34f..42c8f10 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -8,6 +8,12 @@ OPPONENT_PAPER = "B" OPPONENT_SCISSORS = "C" +IDENTICAL_SHAPES = { + OPPONENT_ROCK: ROCK, + OPPONENT_PAPER: PAPER, + OPPONENT_SCISSORS: SCISSORS, +} + OUR_TO_OPPONENT_SHAPE_DEFEAT = { OUR_ROCK: OPPONENT_SCISSORS, OUR_PAPER: OPPONENT_ROCK, @@ -20,10 +26,5 @@ OPPONENT_SCISSORS: OUR_PAPER, } -IDENTICAL_SHAPES = { - OUR_ROCK: OPPONENT_ROCK, - OUR_PAPER: OPPONENT_PAPER, - OUR_SCISSORS: OPPONENT_SCISSORS, -} SHAPE_TO_SCORE = {OUR_ROCK: 1, OUR_PAPER: 2, OUR_SCISSORS: 3} From 2c84a1485c92428d14cbabde20bd4d06a4781345 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:31:39 +0200 Subject: [PATCH 21/34] Normalize input and use generic-shapes instead of player-specific --- puzzles/solutions/2022/d02/p1.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 125ae85..74cecd7 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -8,6 +8,9 @@ def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: :param input_text: puzzle input :return: list of (opponent move, our move) pairs """ + input_text = input_text.translate( + str.maketrans(shapes.IDENTICAL_SHAPES) + ) # Replace opponent shapes with generic shapes. moves = input_text.splitlines() return tuple(tuple(move.split()) for move in moves) From 319fa59199db698e6dd68f42e0ebff1153a604a2 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:33:00 +0200 Subject: [PATCH 22/34] Refactor winning moves mapping --- puzzles/solutions/2022/d02/shapes.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 42c8f10..59df045 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -14,12 +14,11 @@ OPPONENT_SCISSORS: SCISSORS, } -OUR_TO_OPPONENT_SHAPE_DEFEAT = { - OUR_ROCK: OPPONENT_SCISSORS, - OUR_PAPER: OPPONENT_ROCK, - OUR_SCISSORS: OPPONENT_PAPER, +WINNING_MOVES = { + ROCK: SCISSORS, + PAPER: ROCK, + SCISSORS: PAPER, } - OPPONENT_TO_OUR_SHAPE_DEFEAT = { OPPONENT_ROCK: OUR_SCISSORS, OPPONENT_PAPER: OUR_ROCK, From e0a803253722878c870b15f2621a466cb5fe870f Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:33:11 +0200 Subject: [PATCH 23/34] Refactor losing moves mapping --- puzzles/solutions/2022/d02/shapes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 59df045..95ffb7a 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -19,10 +19,10 @@ PAPER: ROCK, SCISSORS: PAPER, } -OPPONENT_TO_OUR_SHAPE_DEFEAT = { - OPPONENT_ROCK: OUR_SCISSORS, - OPPONENT_PAPER: OUR_ROCK, - OPPONENT_SCISSORS: OUR_PAPER, +LOSING_MOVES = { + ROCK: PAPER, + PAPER: SCISSORS, + SCISSORS: ROCK, } From 59c76920d5c187b812e018383185b45838e182bf Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:33:38 +0200 Subject: [PATCH 24/34] Add constant for draw score --- puzzles/solutions/2022/d02/shapes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 95ffb7a..2787ac2 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -25,5 +25,6 @@ SCISSORS: ROCK, } +DRAW_SCORE = 3 SHAPE_TO_SCORE = {OUR_ROCK: 1, OUR_PAPER: 2, OUR_SCISSORS: 3} From 3da780b6f08e88649220f9615d14701bc7e760f5 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:33:44 +0200 Subject: [PATCH 25/34] Add constant for win score --- puzzles/solutions/2022/d02/shapes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 2787ac2..426a813 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -26,5 +26,6 @@ } DRAW_SCORE = 3 +WIN_SCORE = 6 SHAPE_TO_SCORE = {OUR_ROCK: 1, OUR_PAPER: 2, OUR_SCISSORS: 3} From 7ac710dd843fe59ca4d8748be5463d538c0fe272 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 16:34:17 +0200 Subject: [PATCH 26/34] Use new constants in move score function --- puzzles/solutions/2022/d02/p1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 74cecd7..c268ec7 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -22,10 +22,10 @@ def calculate_move_score(move: tuple[str, str]) -> int: """ score = 0 opponent_move, our_move = move - if shapes.OUR_TO_OPPONENT_SHAPE_DEFEAT[our_move] == opponent_move: - score += 6 - elif shapes.IDENTICAL_SHAPES[our_move] == opponent_move: - score += 3 + if shapes.WINNING_MOVES[our_move] == opponent_move: + score += shapes.WIN_SCORE + elif move[0] == move[1]: + score += shapes.DRAW_SCORE score += shapes.SHAPE_TO_SCORE[our_move] return score From 1fe46e1638ce9d6ab015e237e928757eaad37db8 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 17:17:24 +0200 Subject: [PATCH 27/34] Add draw moves mapping --- puzzles/solutions/2022/d02/shapes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index 426a813..b430be7 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -19,6 +19,7 @@ PAPER: ROCK, SCISSORS: PAPER, } +DRAW_MOVES = {shape: shape for shape in (ROCK, PAPER, SCISSORS)} LOSING_MOVES = { ROCK: PAPER, PAPER: SCISSORS, From 7a789874063ec7eb2c97923c02905da6d368fb01 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 17:21:09 +0200 Subject: [PATCH 28/34] Add mapping of outcome to shapes mapping --- puzzles/solutions/2022/d02/shapes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index b430be7..c46f787 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -25,6 +25,7 @@ PAPER: SCISSORS, SCISSORS: ROCK, } +OUTCOME_TO_MAPPING = {"X": LOSING_MOVES, "Y": DRAW_MOVES, "Z": WINNING_MOVES} DRAW_SCORE = 3 WIN_SCORE = 6 From 0577bd0269ccaa20eb0b64ddd074fc1df05fb5b7 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 17:33:04 +0200 Subject: [PATCH 29/34] Use new mappings mapping --- puzzles/solutions/2022/d02/p2.py | 12 ++---------- puzzles/solutions/2022/d02/shapes.py | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 273c11e..c7a2b3d 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -15,16 +15,8 @@ def choose_shape(opponent_move: str, outcome: str) -> str: :param outcome: desired outcome of the move :return: shape to play for the desired outcome to happen """ - if outcome == DEFEAT: - return shapes.OPPONENT_TO_OUR_SHAPE_DEFEAT[opponent_move] - if outcome == DRAW: - for our_shape, opponent_shape in shapes.IDENTICAL_SHAPES.items(): - if opponent_shape == opponent_move: - return our_shape - if outcome == WIN: - for our_shape, opponent_shape in shapes.OUR_TO_OPPONENT_SHAPE_DEFEAT.items(): - if opponent_shape == opponent_move: - return our_shape + mapping = shapes.OUTCOME_TO_MAPPING[outcome] + return mapping[opponent_move] def generate_moves(moves_outcomes: tuple[tuple[str, str]]) -> tuple[tuple[str, str], ...]: diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/shapes.py index c46f787..65398e4 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/shapes.py @@ -30,4 +30,4 @@ DRAW_SCORE = 3 WIN_SCORE = 6 -SHAPE_TO_SCORE = {OUR_ROCK: 1, OUR_PAPER: 2, OUR_SCISSORS: 3} +SHAPE_TO_SCORE = {ROCK: 1, PAPER: 2, SCISSORS: 3} From 1a53dc39ba73f0ffc8dd681589fadc193eaa558d Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 17:33:25 +0200 Subject: [PATCH 30/34] Reformat function definition --- puzzles/solutions/2022/d02/p2.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index c7a2b3d..b6d9ea6 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -19,7 +19,9 @@ def choose_shape(opponent_move: str, outcome: str) -> str: return mapping[opponent_move] -def generate_moves(moves_outcomes: tuple[tuple[str, str]]) -> tuple[tuple[str, str], ...]: +def generate_moves( + moves_outcomes: tuple[tuple[str, str]] +) -> tuple[tuple[str, str], ...]: """ :param moves_outcomes: list of (opponent move, desired outcome) pairs :return: list of (opponent move, desired move for desired outcome to happen) pairs From 1b5a254448bd7a6febbb411bedd41e68784b5687 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 17:33:38 +0200 Subject: [PATCH 31/34] Remove now unused outcome constants --- puzzles/solutions/2022/d02/p2.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index b6d9ea6..e7948f1 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -4,11 +4,6 @@ import shapes -DEFEAT = "X" -DRAW = "Y" -WIN = "Z" - - def choose_shape(opponent_move: str, outcome: str) -> str: """ :param opponent_move: move the opponent played From bc6f747e892e32397fa064f5e218f5d65bb5ee26 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 21:47:17 +0200 Subject: [PATCH 32/34] Fix finding the desired shape Previously the function gave the desired shape as if the given shape was ours and not the opponent's. --- puzzles/solutions/2022/d02/p2.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index e7948f1..9539cfa 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -11,7 +11,9 @@ def choose_shape(opponent_move: str, outcome: str) -> str: :return: shape to play for the desired outcome to happen """ mapping = shapes.OUTCOME_TO_MAPPING[outcome] - return mapping[opponent_move] + for our_move in mapping: + if mapping[our_move] == opponent_move: + return our_move def generate_moves( From de1feba63ba100230d4075b5bcbfd895b55fe415 Mon Sep 17 00:00:00 2001 From: Dan Katzuv Date: Sat, 10 Dec 2022 21:51:48 +0200 Subject: [PATCH 33/34] Replace tuple items accessing with existing variables --- puzzles/solutions/2022/d02/p1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index c268ec7..1a31dd2 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -24,7 +24,7 @@ def calculate_move_score(move: tuple[str, str]) -> int: opponent_move, our_move = move if shapes.WINNING_MOVES[our_move] == opponent_move: score += shapes.WIN_SCORE - elif move[0] == move[1]: + elif opponent_move == our_move: score += shapes.DRAW_SCORE score += shapes.SHAPE_TO_SCORE[our_move] From 8439278ce09b4e0a39c66718539aa574f10a3c1d Mon Sep 17 00:00:00 2001 From: Dan Katzuv <31829093+katzuv@users.noreply.github.com> Date: Sat, 10 Dec 2022 22:03:14 +0200 Subject: [PATCH 34/34] Rename `shapes.py` to `consts.py` This module contains now more constants than just shapes, so a name change is desired. --- puzzles/solutions/2022/d02/{shapes.py => consts.py} | 3 --- puzzles/solutions/2022/d02/p1.py | 12 ++++++------ puzzles/solutions/2022/d02/p2.py | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) rename puzzles/solutions/2022/d02/{shapes.py => consts.py} (86%) diff --git a/puzzles/solutions/2022/d02/shapes.py b/puzzles/solutions/2022/d02/consts.py similarity index 86% rename from puzzles/solutions/2022/d02/shapes.py rename to puzzles/solutions/2022/d02/consts.py index 65398e4..ad0dbc5 100644 --- a/puzzles/solutions/2022/d02/shapes.py +++ b/puzzles/solutions/2022/d02/consts.py @@ -1,6 +1,3 @@ -"""Various constants used for Rock Paper Scissors shapes and other data about them.""" - - ROCK = "X" PAPER = "Y" SCISSORS = "Z" diff --git a/puzzles/solutions/2022/d02/p1.py b/puzzles/solutions/2022/d02/p1.py index 1a31dd2..5154fef 100644 --- a/puzzles/solutions/2022/d02/p1.py +++ b/puzzles/solutions/2022/d02/p1.py @@ -1,6 +1,6 @@ import sys -import shapes +import consts def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: @@ -9,7 +9,7 @@ def get_moves(input_text: str) -> tuple[tuple[str, str], ...]: :return: list of (opponent move, our move) pairs """ input_text = input_text.translate( - str.maketrans(shapes.IDENTICAL_SHAPES) + str.maketrans(consts.IDENTICAL_SHAPES) ) # Replace opponent shapes with generic shapes. moves = input_text.splitlines() return tuple(tuple(move.split()) for move in moves) @@ -22,12 +22,12 @@ def calculate_move_score(move: tuple[str, str]) -> int: """ score = 0 opponent_move, our_move = move - if shapes.WINNING_MOVES[our_move] == opponent_move: - score += shapes.WIN_SCORE + if consts.WINNING_MOVES[our_move] == opponent_move: + score += consts.WIN_SCORE elif opponent_move == our_move: - score += shapes.DRAW_SCORE + score += consts.DRAW_SCORE - score += shapes.SHAPE_TO_SCORE[our_move] + score += consts.SHAPE_TO_SCORE[our_move] return score diff --git a/puzzles/solutions/2022/d02/p2.py b/puzzles/solutions/2022/d02/p2.py index 9539cfa..a5ff22d 100644 --- a/puzzles/solutions/2022/d02/p2.py +++ b/puzzles/solutions/2022/d02/p2.py @@ -1,7 +1,7 @@ import sys +import consts import p1 -import shapes def choose_shape(opponent_move: str, outcome: str) -> str: @@ -10,7 +10,7 @@ def choose_shape(opponent_move: str, outcome: str) -> str: :param outcome: desired outcome of the move :return: shape to play for the desired outcome to happen """ - mapping = shapes.OUTCOME_TO_MAPPING[outcome] + mapping = consts.OUTCOME_TO_MAPPING[outcome] for our_move in mapping: if mapping[our_move] == opponent_move: return our_move