Guest User

Untitled

a guest
Dec 14th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. ########################################################################
  2. #
  3. # Process input data to return the appropriate records or data format.
  4. #
  5. # For this puzzle, the input data is the number of recipes after which
  6. # the 10-digit number will appear, plus the starting state: two recipes
  7. # with scores `[3,7]` and the two elves starting positions at `0` and
  8. # `1`.
  9.  
  10. process_input_data = lambda input_data: (
  11. (int(input_data), (blist([3,7]), 0, 1))
  12. )
  13.  
  14. ########################################################################
  15. #
  16. # determine the new recipes to be added based on the current state.
  17. #
  18. # Returns a list of one or two numbers, the scores of the new recipes
  19. # added.
  20. #
  21. # If the two current recipes sum to less than 10, returns a list of a
  22. # single number which is the sum of the two current recipes.
  23. #
  24. # Otherwise, returns a list of two numbers, the first of which is the
  25. # sum of the two current recipes (integrally) divided by 10, and the
  26. # second of which is the sum of the two recipes mod 10.
  27.  
  28. new_recipes = lambda recipes, pos1, pos2: (
  29.  
  30. # If the two current recipes sum to less than 10, returns a list of a
  31. # single number which is the sum of the two current recipes.
  32.  
  33. blist([ recipes[pos1] + recipes[pos2] ])
  34. if recipes[pos1] + recipes[pos2] < 10
  35. else
  36.  
  37. # Otherwise, returns a list of two numbers, the first of which is the
  38. # sum of the two current recipes (integrally) divided by 10, and the
  39. # second of which is the sum of the two recipes mod 10.
  40.  
  41. blist([
  42. (recipes[pos1] + recipes[pos2]) // 10 ,
  43. (recipes[pos1] + recipes[pos2]) % 10
  44. ])
  45. )
  46.  
  47. ########################################################################
  48. #
  49. # determine the next position for an elf based on the recipes list
  50. # (including the new recipes added this time) and their current position.
  51. #
  52.  
  53. next_position = lambda recipes, position: (
  54. (position + 1 + recipes[position]) % len(recipes)
  55. )
  56.  
  57. ########################################################################
  58. #
  59. # Run one cooking cycle.
  60. #
  61. # Generate a new recipes list from the current state.
  62. # (including the new recipes added this time) and their current position.
  63. #
  64. # Accepts an extra parameter for use in the `accumulate` function.
  65.  
  66. next_cooking_cycle = lambda state, _: (
  67. # use the generator trick to store the new recipes
  68. (
  69. (
  70. recipes,
  71. next_position(recipes, state[1]),
  72. next_position(recipes, state[2])
  73. )
  74. for recipes in [
  75. state[0] + new_recipes(state[0], state[1], state[2])
  76. ]
  77. ).next()
  78. )
  79.  
  80. ########################################################################
  81. #
  82. # Part 1: Run `next_cooking_cycle` until the length of the recipes
  83. # list is at least `input_data` + 10 long. Grab the 10 recipes
  84. # after `input_data`, convert them all to strings, then join
  85. # them together.
  86.  
  87. part_1 = lambda input_data: (
  88. ''.join(
  89. str(digit)
  90. for state in [
  91. itertools.dropwhile(
  92. lambda state: (
  93. len(state[0]) < (input_data[0] + 10)
  94. )
  95. ,
  96. accumulate(
  97. itertools.chain(
  98. input_data[1:2]
  99. ,
  100. itertools.count(1)
  101. )
  102. ,
  103. next_cooking_cycle
  104. )
  105. ).next()
  106. ]
  107. for digit in state[0][input_data[0]:input_data[0]+10]
  108. )
  109. )
Add Comment
Please, Sign In to add comment