From 3cb912f1a759aa9945aa8346de441ca7065d6a12 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Mon, 16 Dec 2024 20:34:13 +0100 Subject: [PATCH] add 2023/day07.1 --- 2023/07/main.py | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 2023/07/main.py diff --git a/2023/07/main.py b/2023/07/main.py new file mode 100644 index 0000000..42a935d --- /dev/null +++ b/2023/07/main.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# -*- encoding: utf-8; py-indent-offset: 4 -*- + +# Author: Sebastian Mark +# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) + +# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string + +# Strength: +# Five of a kind: 6 +# Four of a kind: 5 +# Full house: 4 +# Three of a kind: 3 +# Two pair: 2 +# One Pair: 1 +# High Card: 0 + + +import copy +from collections import Counter + + +def readinput(): + with open("input", "r", encoding="utf-8") as file: + games = [] + for line in file: + hand, bid = line.strip().split() + games.append({"hand": hand, "bid": int(bid), "strength": 0}) + + return games + + +# pylint: disable=inconsistent-return-statements,too-many-return-statements +def calc_strength(hand: str) -> int: + counter = Counter(hand) + highes_count = max(Counter(hand).values()) + + if highes_count == 5: + return 6 # Five of a kind + if highes_count == 4: + return 5 # Four of a kind + if highes_count == 3: + if len(counter) == 3: + return 3 # Three of a kind + return 4 # Full House + if highes_count == 2: + if len(set(hand)) == 3: + return 2 # Two Pair + return 1 # One Pair + if highes_count == 1: + return 0 # High Card + + +def bubblesort_reverse(games: dict) -> dict: + sorted_games = copy.deepcopy(games) + cards = "23456789TJQKA" + + for n in range(len(sorted_games) - 1, 0, -1): + swapped = False + + for i in range(n): + this_game = sorted_games[i] + next_game = sorted_games[i + 1] + + # first sort key: strength (descending) + if this_game["strength"] > next_game["strength"]: + swapped = True + sorted_games[i], sorted_games[i + 1] = ( + sorted_games[i + 1], + sorted_games[i], + ) + + if this_game["strength"] == next_game["strength"]: + # second sort key: cards (descending) + # compare each card, + # if first card is lower, take this order, + # otherwise swap games + for card_a, card_b in zip(this_game["hand"], next_game["hand"]): + if cards.index(card_a) < cards.index(card_b): + break + if cards.index(card_a) > cards.index(card_b): + swapped = True + sorted_games[i], sorted_games[i + 1] = ( + sorted_games[i + 1], + sorted_games[i], + ) + break + + if not swapped: + break + + return sorted_games + + +def main(): + games = readinput() + + # part 1 + for game in games: + game["strength"] = calc_strength(game["hand"]) + + ranked_games = bubblesort_reverse(games) + + winnings = 0 + for i, game in enumerate(ranked_games): + winnings += game["bid"] * (i + 1) + print("Total winnings: %d" % winnings) + + +if __name__ == "__main__": + main()