Skip to content

Commit

Permalink
Improving d17 comments
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed-dash committed Jan 28, 2024
1 parent f08e4ad commit 6f399db
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6655,7 +6655,9 @@
"\n",
"We keep popping next states until we reach the goal. To determine valid next states:\n",
"\n",
"- We create `set` to store states that we've already explored.\n",
"- We create `dict` to store states that we've already seen. \n",
" - Here, we only want to store `(current position, direction, staight_steps)` because we may have entered a cycle and re-entered the same configuration. In this case, we don't want to continue if the cost is higher, because this means we've entered a cycle. I.e. we've repeated a previous state, but with a higher cost. But we can't include the cost in the state, because then the state would always be different if we see a cycle.\n",
" - We could use a `set` to store the seen states. But by using a `dict`, we can also store the cumulative cost to reach this state. This way, we can ignore any previously seen states if the cumulative cost is not less than a cost we've already stored.\n",
"- If we're in our initial position, we don't have a direction yet. So we can try all adjacent squares, and with each, we set `straight steps` to 1.\n",
"- If we're not on the first step, then our valid next moves are left, right, or straight on. We can't go backwards.\n",
" - We can move left relative to our current direction by adding the vector `Point(-dirn.y, dirn.x)`.\n",
Expand Down Expand Up @@ -6700,7 +6702,11 @@
" straight_steps:int = 0 # number of steps taken in one direction without turning\n",
" heapq.heappush(queue, (cost, current_posn, dirn, straight_steps)) # cost must come first for our priority queue\n",
" \n",
" seen = set()\n",
" # Store initial state in the dict, with the cheapest cost to this state.\n",
" # We want to track states we've seen as (current_posn, dirn, straight_steps)\n",
" # But we want to ignore total cost. Because we need to detect \n",
" # if we've entered a configuration we've seen before. E.g. into a cycle.\n",
" seen = { (current_posn, dirn, straight_steps): 0 } # { state: cumulative cost }\n",
" \n",
" while queue:\n",
" cost, current_posn, dirn, straight_steps = heapq.heappop(queue)\n",
Expand All @@ -6709,12 +6715,6 @@
" if current_posn == goal and straight_steps >= pre_turn:\n",
" return cost\n",
" \n",
" # check if we've been in this configuration before\n",
" if (current_posn, dirn, straight_steps) in seen: \n",
" continue\n",
" \n",
" seen.add((current_posn, dirn, straight_steps)) # explored\n",
" \n",
" next_states = [] # point, dirn, steps\n",
" if dirn is None: # we're at the start, so we can go in any direction\n",
" for dir_x, dir_y in ((0, 1), (1, 0), (0, 1), (-1, 0)):\n",
Expand All @@ -6729,13 +6729,17 @@
" if straight_steps < max_straight: # we can move straight ahead. \n",
" next_states.append(((current_posn + dirn), dirn, straight_steps+1))\n",
" \n",
" for neighbour, dirn, new_steps in next_states:\n",
" for next_state in next_states:\n",
" neighbour, dirn, new_steps = next_state\n",
" if (0 <= neighbour.x < len(grid[0]) and 0 <= neighbour.y < len(grid)):\n",
" new_cost = cost + grid[neighbour.y][neighbour.x]\n",
" heapq.heappush(queue, (new_cost, \n",
" neighbour, \n",
" dirn, \n",
" new_steps))\n",
" # enqueue only if it's a new state, or a previous state with better cost\n",
" if next_state not in seen or new_cost < seen[next_state]:\n",
" seen[next_state] = new_cost\n",
" heapq.heappush(queue, (new_cost, \n",
" neighbour, \n",
" dirn, \n",
" new_steps))\n",
" \n",
" raise ValueError(\"No solution found\")"
]
Expand Down Expand Up @@ -6796,21 +6800,21 @@
"\n",
"We're upgrading to _ultra crucibles_. These:\n",
"\n",
"- Require a minimum of 4 blocks before it can turn or stop\n",
"- But can move 10 blocks before turning\n",
"- Require a minimum of 4 blocks before it can turn or stop.\n",
"- But can move 10 blocks before turning.\n",
"\n",
"**Directing the ultra crucible from the lava pool to the machine parts factory, what is the least heat loss it can incur?**\n",
"\n",
"**My solution:**\n",
"\n",
"- Change the `max_straight` value from 3 to 10. So I've parameterised this.\n",
"- Add a new parameter called `pre_turn`, which determines how many `max_straight` is required before we're allowed to turn. So now I perform this test before turning left or right:\n",
"- Add a new parameter called `pre_turn`, which determines the minimum of `straight_steps` before we're allowed to turn. So now I perform this test before turning left or right:\n",
"\n",
"```python\n",
"if straight_steps >= pre_turn\n",
"if straight_steps >= pre_turn:\n",
"```\n",
"\n",
"- Finally, we also need to ensure that we've taken at least four straight steps when we arrive at the goal. So we simply amend our exit condition check like this:\n",
"Finally, we also need to ensure that we've taken at least four straight steps when we arrive at the goal. So we simply amend our exit condition check like this:\n",
"\n",
"```python\n",
" if current_posn == goal and straight_steps >= pre_turn:\n",
Expand Down

0 comments on commit 6f399db

Please sign in to comment.