Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ########################################################################
- #
- # Process input data to return the appropriate records or data format.
- #
- # For this puzzle, the input data is the number of recipes after which
- # the 10-digit number will appear, plus the starting state: two recipes
- # with scores `[3,7]` and the two elves starting positions at `0` and
- # `1`.
- process_input_data = lambda input_data: (
- (int(input_data), (blist([3,7]), 0, 1))
- )
- ########################################################################
- #
- # determine the new recipes to be added based on the current state.
- #
- # Returns a list of one or two numbers, the scores of the new recipes
- # added.
- #
- # If the two current recipes sum to less than 10, returns a list of a
- # single number which is the sum of the two current recipes.
- #
- # Otherwise, returns a list of two numbers, the first of which is the
- # sum of the two current recipes (integrally) divided by 10, and the
- # second of which is the sum of the two recipes mod 10.
- new_recipes = lambda recipes, pos1, pos2: (
- # If the two current recipes sum to less than 10, returns a list of a
- # single number which is the sum of the two current recipes.
- blist([ recipes[pos1] + recipes[pos2] ])
- if recipes[pos1] + recipes[pos2] < 10
- else
- # Otherwise, returns a list of two numbers, the first of which is the
- # sum of the two current recipes (integrally) divided by 10, and the
- # second of which is the sum of the two recipes mod 10.
- blist([
- (recipes[pos1] + recipes[pos2]) // 10 ,
- (recipes[pos1] + recipes[pos2]) % 10
- ])
- )
- ########################################################################
- #
- # determine the next position for an elf based on the recipes list
- # (including the new recipes added this time) and their current position.
- #
- next_position = lambda recipes, position: (
- (position + 1 + recipes[position]) % len(recipes)
- )
- ########################################################################
- #
- # Run one cooking cycle.
- #
- # Generate a new recipes list from the current state.
- # (including the new recipes added this time) and their current position.
- #
- # Accepts an extra parameter for use in the `accumulate` function.
- next_cooking_cycle = lambda state, _: (
- # use the generator trick to store the new recipes
- (
- (
- recipes,
- next_position(recipes, state[1]),
- next_position(recipes, state[2])
- )
- for recipes in [
- state[0] + new_recipes(state[0], state[1], state[2])
- ]
- ).next()
- )
- ########################################################################
- #
- # Part 1: Run `next_cooking_cycle` until the length of the recipes
- # list is at least `input_data` + 10 long. Grab the 10 recipes
- # after `input_data`, convert them all to strings, then join
- # them together.
- part_1 = lambda input_data: (
- ''.join(
- str(digit)
- for state in [
- itertools.dropwhile(
- lambda state: (
- len(state[0]) < (input_data[0] + 10)
- )
- ,
- accumulate(
- itertools.chain(
- input_data[1:2]
- ,
- itertools.count(1)
- )
- ,
- next_cooking_cycle
- )
- ).next()
- ]
- for digit in state[0][input_data[0]:input_data[0]+10]
- )
- )
Add Comment
Please, Sign In to add comment