Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ########################################################################
- #
- # Iterate the carts through one tick.
- #
- # Do this by looping through the length of the carts/tracks strings,
- # processing each cart found (where `carts[index] in '<>^v'`).
- #
- # Use the generator trick to assign a dictionary to `directions` with
- # the following key-value pairs:
- # ```
- # {
- # '<': ( -1, 'v', '<', '^'),
- # '>': ( 1, '^', '>', 'v'),
- # '^': (-width, '<', '^', '>'),
- # 'v': ( width, '>', 'v', '<'),
- # collision_marker: (0,)
- # '\\': { '^': '<', 'v': '>', '>': 'v', '<': '^' },
- # '/': { '^': '>', 'v': '<', '>': '^', '<': 'v' },
- # }
- # ```
- # Each cart direction contains the `(offset, left, straight, right)`
- # tuple for that direction: the `offset` to add to the current index
- # for the cart's next location, and the cart direction if it turns left,
- # straight, or right.
- # The collision marker (`X` by default) is represented by a 0 offset -
- # the cart doesn't # move.
- # In addition, the _track_ symbols `/` and `\\` are represented with a
- # mapping of current direction to new direction,
- #
- # Acucmulate over each index which holds a cart:
- #
- # use the generator trick to assign `cart` to `carts[index]`,
- # `next_turn` to `next_turns[index]`,
- # `cart_turn` to `directions[cart]`,
- # and `next_index` to `index + cart_turn[0]`.
- #
- # Use the generator trick to assign `new_cart` and `new_next_turn`
- # based on `carts[next_index]` and `tracks[next_index]`:
- # If `cart` is the collision marker _or_ `carts[next_index]` is not a space:
- # `new_cart` is the collision marker and
- # `new_next_turn` is ` `.
- # Else if `tracks[next_index]` is a `+`:
- # `new_cart` is `cart_turn[int(next_turn)]` and
- # `new_next_turn` is `str(int(next_turn) % 3 + 1)`.
- # Else if it's in `directions:
- # `new_cart` is `directions[tracks[next_index]][cart]` and
- # `new_next_turn` is `next_turn`.
- # Otherwise (the cart isn't turning):
- # `new_cart` is `cart` and `new_next_turn` is `next_turn`.
- #
- # If `next_index` is the same as `index`, return the current state
- # unchanged.
- # Otherwise, return the `carts` string with `carts[next_index]`
- # replaced by `new_cart` and `carts[index]` replaced by a space, and
- # return the `next_turns` string with `next_turns[next_index]`
- # replaced by `new_next_turn` and `next_turns[index] replaced by a
- # space.
- # (This is slightly complicated by having to do two different
- # replacement expressions based on if `next_index` comes before
- # or after `index`)
- cart_tick = lambda current_state, collision_marker = 'X': (
- # use generator trick to bind `directions`
- # for the scope of the rest of the function
- (
- # Acucmulate over each index which holds a cart:
- reduce(
- lambda current_state, index: (
- # use generator trick to bind values to names
- # for the scope of the expression
- (
- # If `next_index` is the same as `index`, return the current state
- # unchanged.
- (tracks, carts, next_turns, width, height)
- if next_index == index
- else
- # Otherwise, return the `carts` string with `carts[next_index]`
- # replaced by `new_cart` and `carts[index]` replaced by a space, and
- # return the `next_turns` string with `next_turns[next_index]`
- # replaced by `new_next_turn` and `next_turns[index] replaced by a
- # space.
- # (This is slightly complicated by having to do two different
- # replacement expressions based on if `next_index` comes before
- # or after `index`)
- (
- tracks,
- (
- carts[:next_index]
- + new_cart
- + carts[next_index + 1:index]
- + ' '
- + carts[index + 1:]
- )
- if next_index < index
- else (
- carts[:index]
- + ' '
- + carts[index + 1:next_index]
- + new_cart
- + carts[next_index + 1:]
- )
- ,
- (
- next_turns[:next_index]
- + new_next_turn
- + next_turns[next_index + 1:index]
- + ' '
- + next_turns[index + 1:]
- )
- if next_index < index
- else (
- next_turns[:index]
- + ' '
- + next_turns[index + 1:next_index]
- + new_next_turn
- + next_turns[next_index + 1:]
- )
- ,
- width,
- height
- )
- # use the generator trick to assign `cart` to `carts[index]`,
- # `next_turn` to `next_turns[index]`,
- # `cart_turn` to `directions[cart]`,
- # and `next_index` to `index + cart_turn[0]`.
- for (tracks, carts, next_turns, width, height) in [current_state]
- for cart in [carts[index]]
- for next_turn in [next_turns[index]]
- for cart_turn in [directions[cart]]
- for next_index in [index + cart_turn[0]]
- # Use the generator trick to assign `new_cart` and `new_next_turn`
- # based on `carts[next_index]` and `tracks[next_index]`:
- # If `cart` is the collision marker _or_ `carts[next_index]` is not a space:
- # `new_cart` is the collision marker and
- # `new_next_turn` is ` `.
- # Else if `tracks[next_index]` is a `+`:
- # `new_cart` is `cart_turn[int(next_turn)]` and
- # `new_next_turn` is `str(int(next_turn) % 3 + 1)`.
- # Else if it's in `directions:
- # `new_cart` is `directions[tracks[next_index]][cart]` and
- # `new_next_turn` is `next_turn`.
- # Otherwise (the cart isn't turning):
- # `new_cart` is `cart` and `new_next_turn` is `next_turn`.
- for new_cart in [
- collision_marker
- if cart == collision_marker or carts[next_index] != ' '
- else
- cart_turn[int(next_turn)]
- if tracks[next_index] == '+'
- else
- directions[tracks[next_index]][cart]
- if tracks[next_index] in directions
- else
- cart
- ]
- for new_next_turn in [
- ' '
- if cart == collision_marker or carts[next_index] != ' '
- else
- str(int(next_turn) % 3 + 1)
- if tracks[next_index] == '+'
- else
- next_turn
- ]
- ).next()
- )
- ,
- itertools.chain(
- (current_state,),
- itertools.ifilter(
- lambda index: (
- current_state[1][index] in '<>^v'
- )
- ,
- xrange(len(current_state[0]))
- )
- )
- )
- # Use the generator trick to assign a dictionary to `directions` with
- # the following key-value pairs:
- for directions in [
- {
- '<': ( -1, 'v', '<', '^'),
- '>': ( 1, '^', '>', 'v'),
- '^': (-current_state[3], '<', '^', '>'),
- 'v': ( current_state[3], '>', 'v', '<'),
- collision_marker: (0,),
- '\\': { '^': '<', 'v': '>', '>': 'v', '<': '^' },
- '/': { '^': '>', 'v': '<', '>': '^', '<': 'v' },
- }
- ]
- ).next()
- )
Add Comment
Please, Sign In to add comment