daily pastebin goal
76%
SHARE
TWEET

Untitled

a guest Dec 13th, 2018 45 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ########################################################################
  2. #
  3. # Iterate the carts through one tick.
  4. #
  5. # Do this by looping through the length of the carts/tracks strings,
  6. # processing each cart found (where `carts[index] in '<>^v'`).
  7. #
  8. # Use the generator trick to assign a dictionary to `directions` with
  9. # the following key-value pairs:
  10. # ```
  11. #     {
  12. #         '<': (    -1, 'v', '<', '^'),
  13. #         '>': (     1, '^', '>', 'v'),
  14. #         '^': (-width, '<', '^', '>'),
  15. #         'v': ( width, '>', 'v', '<'),
  16. #         collision_marker: (0,)
  17. #         '\\': { '^': '<', 'v': '>', '>': 'v', '<': '^' },
  18. #         '/':  { '^': '>', 'v': '<', '>': '^', '<': 'v' },
  19. #     }
  20. # ```
  21. # Each cart direction contains the `(offset, left, straight, right)`
  22. # tuple for that direction: the `offset` to add to the current index
  23. # for the cart's next location, and the cart direction if it turns left,
  24. # straight, or right.
  25. # The collision marker (`X` by default) is represented by a 0 offset -
  26. # the cart doesn't # move.
  27. # In addition, the _track_ symbols `/` and `\\` are represented with a
  28. # mapping of current direction to new direction,
  29. #
  30. # Acucmulate over each index which holds a cart:
  31. #
  32. #     use the generator trick to assign `cart` to `carts[index]`,
  33. #     `next_turn` to `next_turns[index]`,
  34. #     `cart_turn` to `directions[cart]`,
  35. #     and `next_index` to `index + cart_turn[0]`.
  36. #
  37. #     Use the generator trick to assign `new_cart` and `new_next_turn`
  38. #     based on `carts[next_index]` and `tracks[next_index]`:
  39. #         If `cart` is the collision marker _or_ `carts[next_index]` is not a space:
  40. #             `new_cart` is the collision marker and
  41. #             `new_next_turn` is ` `.
  42. #         Else if `tracks[next_index]` is a `+`:
  43. #             `new_cart` is `cart_turn[int(next_turn)]` and
  44. #             `new_next_turn` is `str(int(next_turn) % 3 + 1)`.
  45. #         Else if it's in `directions:
  46. #             `new_cart` is `directions[tracks[next_index]][cart]` and
  47. #             `new_next_turn` is `next_turn`.
  48. #         Otherwise (the cart isn't turning):
  49. #             `new_cart` is `cart` and `new_next_turn` is `next_turn`.
  50. #
  51. #     If `next_index` is the same as `index`, return the current state
  52. #     unchanged.
  53. #     Otherwise, return the `carts` string with `carts[next_index]`
  54. #     replaced by `new_cart` and `carts[index]` replaced by a space, and
  55. #     return the `next_turns` string with `next_turns[next_index]`
  56. #     replaced by `new_next_turn` and `next_turns[index] replaced by a
  57. #     space.
  58. #     (This is slightly complicated by having to do two different
  59. #     replacement expressions based on if `next_index` comes before
  60. #     or after `index`)
  61.  
  62. cart_tick = lambda current_state, collision_marker = 'X': (
  63.             # use generator trick to bind `directions`
  64.             # for the scope of the rest of the function
  65.             (
  66.  
  67. # Acucmulate over each index which holds a cart:
  68.  
  69.                 reduce(
  70.  
  71.                     lambda current_state, index: (
  72.                         # use generator trick to bind values to names
  73.                         # for the scope of the expression
  74.                         (
  75.  
  76. #     If `next_index` is the same as `index`, return the current state
  77. #     unchanged.
  78.  
  79.                             (tracks, carts, next_turns, width, height)
  80.                             if next_index == index
  81.                             else
  82.  
  83. #     Otherwise, return the `carts` string with `carts[next_index]`
  84. #     replaced by `new_cart` and `carts[index]` replaced by a space, and
  85. #     return the `next_turns` string with `next_turns[next_index]`
  86. #     replaced by `new_next_turn` and `next_turns[index] replaced by a
  87. #     space.
  88. #     (This is slightly complicated by having to do two different
  89. #     replacement expressions based on if `next_index` comes before
  90. #     or after `index`)
  91.  
  92.                                 (
  93.                                     tracks,
  94.                                     (
  95.                                         carts[:next_index]
  96.                                         + new_cart
  97.                                         + carts[next_index + 1:index]
  98.                                         + ' '
  99.                                         + carts[index + 1:]
  100.                                     )
  101.                                     if next_index < index
  102.                                     else (
  103.                                         carts[:index]
  104.                                         + ' '
  105.                                         + carts[index + 1:next_index]
  106.                                         + new_cart
  107.                                         + carts[next_index + 1:]
  108.                                     )
  109.                                     ,
  110.                                     (
  111.                                         next_turns[:next_index]
  112.                                         + new_next_turn
  113.                                         + next_turns[next_index + 1:index]
  114.                                         + ' '
  115.                                         + next_turns[index + 1:]
  116.                                     )
  117.                                     if next_index < index
  118.                                     else (
  119.                                         next_turns[:index]
  120.                                         + ' '
  121.                                         + next_turns[index + 1:next_index]
  122.                                         + new_next_turn
  123.                                         + next_turns[next_index + 1:]
  124.                                     )
  125.                                     ,
  126.                                     width,
  127.                                     height
  128.                                 )
  129.  
  130. #     use the generator trick to assign `cart` to `carts[index]`,
  131. #     `next_turn` to `next_turns[index]`,
  132. #     `cart_turn` to `directions[cart]`,
  133. #     and `next_index` to `index + cart_turn[0]`.
  134.  
  135.                             for (tracks, carts, next_turns, width, height) in [current_state]
  136.                             for cart in [carts[index]]
  137.                             for next_turn in [next_turns[index]]
  138.                             for cart_turn in [directions[cart]]
  139.                             for next_index in [index + cart_turn[0]]
  140.  
  141. #     Use the generator trick to assign `new_cart` and `new_next_turn`
  142. #     based on `carts[next_index]` and `tracks[next_index]`:
  143. #         If `cart` is the collision marker _or_ `carts[next_index]` is not a space:
  144. #             `new_cart` is the collision marker and
  145. #             `new_next_turn` is ` `.
  146. #         Else if `tracks[next_index]` is a `+`:
  147. #             `new_cart` is `cart_turn[int(next_turn)]` and
  148. #             `new_next_turn` is `str(int(next_turn) % 3 + 1)`.
  149. #         Else if it's in `directions:
  150. #             `new_cart` is `directions[tracks[next_index]][cart]` and
  151. #             `new_next_turn` is `next_turn`.
  152. #         Otherwise (the cart isn't turning):
  153. #             `new_cart` is `cart` and `new_next_turn` is `next_turn`.
  154.  
  155.                             for new_cart in [
  156.                                 collision_marker
  157.                                 if cart == collision_marker or carts[next_index] != ' '
  158.                                 else
  159.                                     cart_turn[int(next_turn)]
  160.                                     if tracks[next_index] == '+'
  161.                                     else
  162.                                         directions[tracks[next_index]][cart]
  163.                                         if tracks[next_index] in directions
  164.                                         else
  165.                                             cart
  166.                             ]
  167.                             for new_next_turn in [
  168.                                 ' '
  169.                                 if cart == collision_marker or carts[next_index] != ' '
  170.                                 else
  171.                                     str(int(next_turn) % 3 + 1)
  172.                                     if tracks[next_index] == '+'
  173.                                     else
  174.                                         next_turn
  175.                             ]
  176.  
  177.                         ).next()
  178.                     )
  179.  
  180.                     ,
  181.  
  182.                     itertools.chain(
  183.                         (current_state,),
  184.                         itertools.ifilter(
  185.                             lambda index: (
  186.                                 current_state[1][index] in '<>^v'
  187.                             )
  188.                             ,
  189.                             xrange(len(current_state[0]))
  190.                         )
  191.                     )
  192.  
  193.                 )
  194.  
  195. # Use the generator trick to assign a dictionary to `directions` with
  196. # the following key-value pairs:
  197.  
  198.                 for directions in [
  199.                     {
  200.                         '<': (               -1, 'v', '<', '^'),
  201.                         '>': (                1, '^', '>', 'v'),
  202.                         '^': (-current_state[3], '<', '^', '>'),
  203.                         'v': ( current_state[3], '>', 'v', '<'),
  204.                         collision_marker: (0,),
  205.                         '\\': { '^': '<', 'v': '>', '>': 'v', '<': '^' },
  206.                         '/':  { '^': '>', 'v': '<', '>': '^', '<': 'v' },
  207.                     }
  208.                 ]
  209.  
  210.             ).next()
  211.         )
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top