### re: AoC Day 14: Chocolate Charts VIEW POST

OK, I'm caving. I'm going to be doing these in Python from here on out, I think. They're getting tough enough that I don't need to be fighting with Rust's borrow checker and the challenge itself. It feels like trying to win a debate on foreign policy in Mandarin. Also, Python is way more fun. And it's Christmas, so Merry Christmas to me and Python. 😬

Anyways, enough whining from me. Here's my solution from day 14.

``````"""Day 14: Chocolate Charts

Figuring out scores for hot chocolate through iterative process.
"""

from typing import List

class Board:
"""Keeps track of hot chocolate recipe scores"""

def __init__(self, elf1_score, elf2_score):
self.scores = [elf1_score, elf2_score]
self.elf1 = 0
self.elf2 = 1

def generate_new_recipes(self):
"""Generates one or two new recipes by combining the current ones"""
new_score = self.scores[self.elf1] + self.scores[self.elf2]
self.scores.extend(Board.digits(new_score))

@staticmethod
def digits(number: int) -> List[int]:
"""Given a number, returns a list of its digits"""
return [int(digit) for digit in str(number)]

def select_new_recipes(self):
"""Each elf selects a new recipe based on their current one"""
self.elf1 = (self.elf1 + self.scores[self.elf1] + 1) % len(self.scores)
self.elf2 = (self.elf2 + self.scores[self.elf2] + 1) % len(self.scores)

def tick(self):
"""One iteration cycle of creating recipes"""
self.generate_new_recipes()
self.select_new_recipes()

def generate_n_scores(self, n: int) -> List[int]:
"""Adds *at least* n scores to the board (may be one extra)"""
current_scores = len(self.scores)
while len(self.scores) < current_scores + n:
self.tick()

return self.scores[current_scores:current_scores + n]

def get_scores(self, start: int, count: int) -> List[int]:
"""Returns the scores on the board.  1-based counting"""
return self.scores[start - 1:start - 1 + count]

def find_numbers(self, num: str) -> int:
"""Find the start index of a given string of digits"""
digits = Board.digits(num)

if len(self.scores) < len(digits):
self.generate_n_scores(len(digits) - len(self.scores))

last_len = len(digits)
while True:
self.tick()
if len(self.scores) == last_len + 2:
if self.scores[-len(digits) - 1: -1] == digits:
return len(self.scores) - len(digits) - 1
if self.scores[-len(digits):] == digits:
return len(self.scores) - len(digits)

last_len = len(self.scores)

if __name__ == "__main__":
# Part 1
board = Board(3, 7)
board.generate_n_scores(440231 + 10)
print("".join(str(i) for i in board.get_scores(440231 + 1, 10)))

# Part 2
board = Board(3, 7)
print(board.find_numbers("440231"))
``````
code of conduct - report abuse  