510 likes | 644 Views
Clue Paths. The Challenge. Highlight all the squares that can be reached in # of steps shown on one die Move only up/down/left/right (no diagonal) Do not touch any location more than one time Highlight only the final squares, not the paths . Roll a 1. The Challenge. Roll a 2.
E N D
The Challenge Highlight all the squares that can be reached in # of steps shown on one die Move only up/down/left/right (no diagonal) Do not touch any location more than one time Highlight only the final squares, not the paths Roll a 1
The Challenge Roll a 2
Simplify for now Forget about doors and rooms. Number each square Create an adjacency list. NOTE: adjacency lists will be even more handy in the clue layout, because a square is not necessarily attached to each of its neighbors. By creating the adjacency list when the board is loaded, we can simplify the code for the path-finding algorithm. 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6] 8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] With your partner: What is this? How would you write a program to create?
Calculating the Adjacency Lists 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6] Notice that for each cell, you have at most 4 neighbors. To calculate the adjacency list: for each cell look at each neighbor if it is a valid index add it to the adjacency list What data structure would you use for the adjacency list?
Calculating Neighbors 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6] • Could be stored in a map • Need to consider: how to convert from 2D to 1D. Write a helper function, e.g., • calcIndex(0, 0) => 0 • calcIndex(1, 1) => 5 • calcIndex(1, 3) => 7 • What are some other alternatives? • To facilitate code swap, it will help if we all take a similar approach.
Memory Alias Review • Remember that it’s possible for two unique variables to point to the same memory location someFn (in another class) { localVar = mc.getMyList(); } 0x100 MyClass mc myList localVar 0x100 0x100 If I modify localVar, it also changes myList!
Memory Alias Continued • In C++, what was the purpose of the copy constructor? • In Java, the clone method serves the same purpose MyClass mc myList 0x100 0x300 0x200 0x100 0x200 0x300 0x0 MyClass mc2 (created by assignment, e.g., mc2 =mc; ) myList 0x100 0x300 0x200 0x100 0x200 0x300 0x0 MyClass mc3 (created using clone, e.g., mc3 = mc.clone(); ) myList 0x500 0x700 0x600 0x500 0x600 0x700 0x0
Recursion Review • Base case – causes recursion to end • Recursive call – to same function • Progress toward base case
Simple Example public static int factorial(int n) { if(n==1) return 1; return factorial(n-1) * n; } public static void main(String[] args) { System.out.println(factorial(3)); } Very Quick Ex: How would factorial(3) be calculated? (trace the code)
Sometimes need “setup” first • Example: drawing a fractal • drawFractal: setup center x, center y, x0 and y0 • Call drawFractalLine with length, theta, order • drawFractalLine – draws a line, does a recursive call with order-1 • What’s the point? User calls drawFractal, recursive function is drawFractalLine. • Our algorithm has similar structure from: Thinking Recursively in Java, Eric Roberts
0 1 2 3 startTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 adjacencies Goal: Targets with paths of length 2 from cell 4 Answer: Shown in green above 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] • Set up for recursive call • visited array, all False (used to avoid backtracking) • adjacency matrix has been calculated • empty set of targets • set visited[start location] to True • call calcTargets with start location (4) and number of steps (2) targets: none yet Why can’t these steps be in recursive fn?
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 calcTarget pseudocode adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] Parameters: thisCell and numSteps Set adjacentCells to all cells adjacent to thisCell that have not been visited NOTE: do not modify adjacencies, create a new list! for each adjCell in adjacentCells -- set visited[adjCell] to True -- if numSteps == 1, add adjCell to Targets -- else call calcTargets with adjCell, numSteps-- -- set visited[adjCell] to False recursive call!
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: (none yet) adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells) -- set visited to True -- (if number of steps == 1 … ) -- else call calcTargets with adjCell , numStep-- -- (when we return….set visited to False)
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: (none yet) adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells… current is 8) -- set visited[8] to True -- (if number of steps == 1 … ) -- else call calcTargets with adjCell, numStep-- -- (when we return….set visited to False)
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: (none yet) adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells… current is 8) -- set visited[8] to True -- (if number of steps == 1 … it’s not) -- else call calcTargets with adjCell (8), numStep-- -- (when we return….set visited to False) recursive call! next slide
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: none yet adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (but remember, don’t modify list of all adjacencies!) (for each cell in adjacentCells) -- set visited[12] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: none yet adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 12) -- set visited[12] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 12) -- set visited[12] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 12) -- set visited[12] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited[12] to False then move to next cell in for loop, next slide
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited[9] to False then move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =8, numSteps=1 Set adjacentCells to all cells adjacent to 8 that have not been visited… [12, 9] not 4 (for each cell in adjacentCells, current is END) -- set visited[9] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False end of for loop, return
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 8 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 8) -- set visited[9] to True -- if number of steps == 1… yes! update Targets -- (else call calcTargets with adjCell, numSteps--) -- when we return, set visited[8] to False end of for loop, return from recursive call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 8 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 5) -- set visited[5] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell, numSteps--) -- when we return, set visited to False next item in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 8 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 5) -- set visited[5] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (5), numSteps--) -- when we return, set visited to False recursive call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [1, 6, 9, 4]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9]… not 4! (for each cell in adjacentCells) -- set visited[1] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (5), numSteps--) -- when we return, set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [1, 6, 9, 4]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9]… not 4! (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (5), numSteps--) -- when we return, set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (5), numSteps--) -- when we return, set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (5), numSteps--) -- set visited[1] to False then move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 3] (for each cell in adjacentCells, current is 6) -- set visited[6] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (5), numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 6) -- set visited[6] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (5), numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 6) -- set visited[6] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (5), numSteps--) -- set visited[6] to False then move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6… no need to add 9 again adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is 9) -- set visited[9] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- set visited[9] to False then move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =5, numSteps=1 Set adjacentCells to all cells adjacent to 5 that have not been visited… [1, 6, 9] (for each cell in adjacentCells, current is END) -- set visited[9] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- set visited[9] to False end of for loop, return from recursive call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 5) -- set visited[5] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- when return from call, set visited[5] to False move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 0) -- set visited[0] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell, numSteps--) -- set visited to False move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 4 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 0) -- set visited[0] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False another recursive call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =0, numSteps=1 Set adjacentCells to all cells adjacent to 0 that have not been visited… [1] … not 4! (for each cell in adjacentCells) -- set visited[0] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False another recursive call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =0, numSteps=1 Set adjacentCells to all cells adjacent to 0 that have not been visited… [1] … not 4! (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… it’s not -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 … 1 is already in the set adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =0, numSteps=1 Set adjacentCells to all cells adjacent to 0 that have not been visited… [1] … not 4! (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =0, numSteps=1 Set adjacentCells to all cells adjacent to 0 that have not been visited… [1] … not 4! (for each cell in adjacentCells, current is 1) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (0), numSteps--) -- set visited[1] to False move to next cell in for loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =0, numSteps=1 Set adjacentCells to all cells adjacent to 0 that have not been visited… [1] … not 4! (for each cell in adjacentCells, current is END) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False end of for loop, return from call
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 0 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is 0) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (0), numSteps--) -- set visited[0] to False move to next item in loop
0 1 2 3 calcTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 Set adjacentCells to all cells adjacent to 0 that have not been visited… [8, 5, 0] (for each cell in adjacentCells, current is END) -- set visited[1] to True -- if number of steps == 1… yes! update targets -- (else call calcTargets with adjCell (0), numSteps--) -- set visited to False end of loop, return from call
0 1 2 3 startTargets 0 1 2 3 visited 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Targets: 12, 9, 1, 6 adjacencies 0 => [4, 1]1 => [0, 5, 2]2 => [1, 6, 3]3 => [2, 7]4 => [8, 5, 0]5 => [4, 9, 6, 1]6 => [2, 5, 10, 7]7 => [11, 3, 6]8 => [12, 9, 4]9 => [13, 10, 5, 8]10 => [14, 11, 6, 9]11 => [15, 7, 10]12 => [13, 8]13 => [14, 9, 12]14 => [15, 10, 13]15 => [11, 14] calcTargets call: thisCell =4, numSteps=2 We have now returned to the startTargets instance variable targets contains answer end of loop, return from call
HINT • You can use clone to create a list of adjacent cells that have not been visited. Or create a new list containing just the unvisted cells. If you just modify the existing list, your code will fail. get(0) gets 0x100 if I remove an element, I update the list in my hash map 1 -> 4 0x100 0x200 0x300 0x400 0x500 0x600 0 1 2 3 4 5