Let's see how far I get this year.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

day04-2.py 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from copy import deepcopy
  2. from helpers import Helper
  3. helper = Helper(debug=True)
  4. load_input = helper.load_input
  5. debug = helper.debug
  6. class Card:
  7. """ A single scratch-off card for AOC 2023 day 4. """
  8. def __init__(self, input_line):
  9. card_id, numbers = input_line.split(": ")
  10. winning, have = numbers.split(" | ")
  11. self.idnum = int(card_id.split()[1])
  12. self.winning = [int(n) for n in winning.split()]
  13. self.have = [int(n) for n in have.split()]
  14. @property
  15. def num_winners(self) -> int:
  16. winners = 0
  17. for number in self.have:
  18. if number in self.winning:
  19. winners += 1
  20. return winners
  21. @property
  22. def score(self) -> int:
  23. return 2**(self.num_winners-1) if self.num_winners > 0 else 0
  24. def main():
  25. lines = load_input(4)
  26. cards = []
  27. for line in lines:
  28. cards.append(Card(input_line=line))
  29. # For every matching number #M (that's ordinal, not the actual matching number)
  30. # on card N, I get a copy of card N+M. So if card 1 has three matching numbers,
  31. # I get copies of cards 2 (1+1), 3 (1+2), and 4 (1+3).
  32. # Don't process this iteratively; you will quickly overwhelm the interpreter.
  33. # You don't actually need a new copy of each card. You just need to know
  34. # how many copies of each card you have.
  35. cards_dicts = []
  36. for card in cards:
  37. # Each card has a count of how many of it we have
  38. cards_dicts.append({"card": card, "count": 1})
  39. for i, card in enumerate(cards_dicts):
  40. # NOT the score, that way lies madness and IndexErrors
  41. winning_nums = card["card"].num_winners
  42. current_add = 1
  43. while winning_nums > 0:
  44. # Each copy of the current card adds 1 count to each target card
  45. cards_dicts[i + current_add]["count"] += card["count"]
  46. winning_nums -= 1
  47. current_add += 1
  48. print(f"Total cards: {sum([v['count'] for v in cards_dicts])}")
  49. if __name__ == "__main__":
  50. main()