Guest User

Untitled

a guest
Dec 14th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.60 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 2: Split `input_data` into a list of integers.
  83. # Run `next_cooking_cycle` until the `input_data` list appears
  84. # either at the end or 1 back from the end of the recipes list.
  85. # Return the number of recipes before the `input_data` list.
  86.  
  87. part_2 = lambda input_data: (
  88. # generator trick to bind values to names
  89. (
  90.  
  91. # Return the number of recipes before the `input_data` list.
  92.  
  93. len(state[0]) - len(input_data_list)
  94. if state[0][-len(input_data_list):] == input_data_list
  95. else
  96. len(state[0]) - len(input_data_list) - 1
  97.  
  98. # Split `input_data` into a list of integers.
  99.  
  100. for input_data_list in [
  101. blist(
  102. int(digit)
  103. for digit in str(input_data[0])
  104. )
  105. ]
  106. for state in [
  107.  
  108. # ... until the `input_data` list appears
  109. # either at the end or 1 back from the end of the recipes list.
  110.  
  111. itertools.dropwhile(
  112. lambda state: (
  113. state[0][-len(input_data_list):] != input_data_list
  114. and state[0][-len(input_data_list)-1:-1] != input_data_list
  115. )
  116. ,
  117.  
  118. # Run `next_cooking_cycle` ...
  119.  
  120. accumulate(
  121. itertools.chain(
  122. input_data[1:2]
  123. ,
  124. itertools.count(1)
  125. )
  126. ,
  127. next_cooking_cycle
  128. )
  129. ).next()
  130. ]
  131. ).next()
  132. )
Add Comment
Please, Sign In to add comment