Skip to content

Commit

Permalink
AoC 2023 Day 7 Part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
pareronia committed Dec 7, 2023
1 parent 7cd6bd1 commit c1f7263
Showing 1 changed file with 125 additions and 0 deletions.
125 changes: 125 additions & 0 deletions src/main/python/AoC2023_07.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#! /usr/bin/env python3
#
# Advent of Code 2023 Day 7
#

from __future__ import annotations

import sys
from collections import Counter
from functools import total_ordering
from typing import NamedTuple

from aoc.common import InputData
from aoc.common import SolutionBase
from aoc.common import aoc_samples
from aoc.common import log

TEST = """\
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
"""

VALUES = {
"2": 2,
"3": 3,
"4": 4,
"5": 5,
"6": 6,
"7": 7,
"8": 8,
"9": 9,
"T": 10,
"J": 11,
"Q": 12,
"K": 13,
"A": 14,
}


@total_ordering
class Hand(NamedTuple):
cards: str
bid: int

@classmethod
def from_input(cls, line: str) -> Hand:
c, b = line.split()
return Hand(c, int(b))

def value(self) -> int:
c = Counter(self.cards)
if 5 in c.values():
type = 1000
elif 4 in c.values():
type = 900
elif sorted(c.values()) == [2, 3]:
type = 800
elif 3 in c.values():
type = 700
elif sorted(c.values()) == [1, 2, 2]:
type = 600
elif 2 in c.values():
type = 500
else:
type = 400
return type

def strength(self) -> list[int]:
return [VALUES[self.cards[i]] for i in range(5)]

def __eq__(self, other: Hand) -> bool:
if self.value() == other.value():
return self.strength() == other.strength()
else:
return False

def __lt__(self, other: Hand) -> bool:
if self.value() < other.value():
return True
elif self.value() == other.value():
return self.strength() < other.strength()
return False


Input = list[Hand]
Output1 = int
Output2 = int


class Solution(SolutionBase[Input, Output1, Output2]):
def parse_input(self, input_data: InputData) -> Input:
return [Hand.from_input(line) for line in input_data]

def part_1(self, hands: Input) -> Output1:
hands = sorted(hands)
log(hands)
ans = sum((i + 1) * hands[i].bid for i in range(len(hands)))
log(ans)
return ans

def part_2(self, input: Input) -> Output2:
return 0

@aoc_samples(
(
("part_1", TEST, 6440),
# ("part_2", TEST, "TODO"),
)
)
def samples(self) -> None:
pass


solution = Solution(2023, 7)


def main() -> None:
solution.run(sys.argv)


if __name__ == "__main__":
main()

0 comments on commit c1f7263

Please sign in to comment.