diff --git a/setup.py b/setup.py index 00a4a08..93f6e82 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='TraverseCraft', - version='1.0.0', + version='1.1.0', author='Srajan Chourasia, Varun Patrikar', author_email='srajanstark.ash@gmail.com, patrikarvarun@gmail.com', maintainer='Srajan Chourasia, Varun Patrikar', diff --git a/src/traverseCraft/world.py b/src/traverseCraft/world.py index 654258d..975a908 100644 --- a/src/traverseCraft/world.py +++ b/src/traverseCraft/world.py @@ -613,7 +613,7 @@ def _check_tree_format(self,treeWorldInfo): # Ensure all nodes in 'adj' and 'goals' are in 'position' position_keys = set(position.keys()) adj_keys = set(adj.keys()) - root_key = set(treeWorldInfo['root']) + root_key = set([treeWorldInfo['root']]) goals_set = set(goals) if not root_key.issubset(position_keys): diff --git a/tutorials/Grid World/leetcode_number_of_islands.py b/tutorials/Grid World/leetcode_number_of_islands.py new file mode 100644 index 0000000..e2aba40 --- /dev/null +++ b/tutorials/Grid World/leetcode_number_of_islands.py @@ -0,0 +1,63 @@ +from traverseCraft.world import CreateGridWorld +from traverseCraft.agent import GridAgent + +def solver(grid, n:int, m:int, i:int, j:int, agent:GridAgent)->int: + # Base Case + grid[i][j] = -1 + # move top + if(i > 0 and grid[i-1][j] == 1 and agent.moveAgent(i - 1, j, delay=0.28)): + solver(grid, n, m, i - 1, j, agent) + agent.moveAgent(i, j) + # move down + if(i < (n - 1) and grid[i+1][j] == 1 and agent.moveAgent(i + 1, j, delay=0.28)): + solver(grid, n, m, i + 1, j, agent) + agent.moveAgent(i, j) + # move right + if(j < (m - 1) and grid[i][j+1] == 1 and agent.moveAgent(i, j + 1, delay=0.28)): + solver(grid, n, m, i, j + 1, agent) + agent.moveAgent(i, j) + # move left + if(j > 0 and grid[i][j-1] == 1 and agent.moveAgent(i, j - 1, delay=0.28)): + solver(grid, n, m, i, j - 1, agent) + agent.moveAgent(i, j) + +def numIslands(grid, n:int, m:int, agent:GridAgent)->int: + ans = 0 + for i in range(n): + for j in range(m): + if(grid[i][j] == 1): + ans += 1 + if((i + j) != 0): + agent.moveAgent(i, j) + solver(grid, n, m, i, j, agent) + return ans + +if __name__ == "__main__": + n = 5 + m = 7 + grid = [[1, 1, 0, 0, 1, 1, 1], + [1, 1, 0, 0, 1, 1, 1], + [0, 0, 1, 1, 0, 0, 0], + [1, 1, 0, 0, 0, 1, 1], + [1, 1, 1, 0, 1, 1, 1]] + water = [] + land = [] + for i in range(n): + for j in range(m): + if(grid[i][j] == 0): + water.append([i, j]) + else: + land.append([i, j]) + + world = CreateGridWorld(worldName = "Leetcode Number of Islands", rows = n, cols = m, cellSize = 36) + world.constructWorld() + world.setBlockPath(water) + world.setGoalState(land) + agent = GridAgent(world, agentName = "Robot") + def sim(): + print("Starting the simulation!") + print("Number of unique Islands: ", numIslands(grid, n, m, agent)) + print("Simulation Completed!") + world.setAgent(agent) + agent.setAlgorithmCallBack(sim) + world.showWorld() diff --git a/tutorials/Grid World/leetcode_unique_path.py b/tutorials/Grid World/leetcode_unique_path.py new file mode 100644 index 0000000..9a3dcfe --- /dev/null +++ b/tutorials/Grid World/leetcode_unique_path.py @@ -0,0 +1,40 @@ +from traverseCraft.world import CreateGridWorld +from traverseCraft.agent import GridAgent + +def solver(n:int, m:int, i:int, j:int, agent:GridAgent)->int: + # Base Case + if(i == (n - 1) and j == (m - 1)): + return 1 + elif((i < 0) or (j < 0) or (i == n) or (j == m)): + return 0 + + ans = 0 + + # move right + if(agent.moveAgent(i, j + 1, delay=0.28)): + ans += solver(n, m, i, j + 1, agent) + agent.moveAgent(i, j) + + # move down + if(agent.moveAgent(i + 1, j, delay=0.28)): + ans += solver(n, m, i + 1, j, agent) + agent.moveAgent(i, j) + + return ans + +def uniquePaths(m:int, n:int, agent:GridAgent)->int: + return solver(m, n, 0, 0, agent) + +if __name__ == "__main__": + m = 3 + n = 7 + world = CreateGridWorld(worldName = "Leetcode Unique Paths", rows = m, cols = n, cellSize = 36) + world.constructWorld() + agent = GridAgent(world, agentName = "Robot") + def sim(): + print("Starting the simulation!") + print("Number of unique paths: ", uniquePaths(m, n, agent)) + print("Simulation Completed!") + world.setAgent(agent) + agent.setAlgorithmCallBack(sim) + world.showWorld() diff --git a/tutorials/Grid World/leetcode_unique_path_2.py b/tutorials/Grid World/leetcode_unique_path_2.py new file mode 100644 index 0000000..e8b7dba --- /dev/null +++ b/tutorials/Grid World/leetcode_unique_path_2.py @@ -0,0 +1,41 @@ +from traverseCraft.world import CreateGridWorld +from traverseCraft.agent import GridAgent + +def solver(n:int, m:int, i:int, j:int, agent:GridAgent)->int: + # Base Case + if(i == (n - 1) and j == (m - 1)): + return 1 + elif((i < 0) or (j < 0) or (i == n) or (j == m)): + return 0 + + ans = 0 + + # move right + if(agent.moveAgent(i, j + 1, delay=0.28)): + ans += solver(n, m, i, j + 1, agent) + agent.moveAgent(i, j) + + # move down + if(agent.moveAgent(i + 1, j, delay=0.28)): + ans += solver(n, m, i + 1, j, agent) + agent.moveAgent(i, j) + + return ans + +def uniquePaths(m:int, n:int, agent:GridAgent)->int: + return solver(m, n, 0, 0, agent) + +if __name__ == "__main__": + m = 4 + n = 7 + world = CreateGridWorld(worldName = "Leetcode Unique Paths 2", rows = m, cols = n, cellSize = 36) + world.constructWorld() + world.setBlockPath([[0,5], [2,2], [1,4], [3,5]]) + agent = GridAgent(world, agentName = "Robot") + def sim(): + print("Starting the simulation!") + print("Number of unique paths: ", uniquePaths(m, n, agent)) + print("Simulation Completed!") + world.setAgent(agent) + agent.setAlgorithmCallBack(sim) + world.showWorld() diff --git a/tutorials/Tree World/leetcode_level_order_traversal.py b/tutorials/Tree World/leetcode_level_order_traversal.py new file mode 100644 index 0000000..1d0e0d6 --- /dev/null +++ b/tutorials/Tree World/leetcode_level_order_traversal.py @@ -0,0 +1,69 @@ +from traverseCraft.world import CreateTreeWorld +from traverseCraft.agent import TreeAgent +from collections import deque + +def levelOrderTraversal(rootId: int, agent: TreeAgent, world: CreateTreeWorld): + if rootId is None: + return [] + + queue = deque([rootId]) + result = [] + + while queue: + level_size = len(queue) + current_level = [] + + for _ in range(level_size): + node_id = queue.popleft() + agent.moveAgent(node_id, delay=0.5) + current_level.append(node_id) + + for child in world.nodeMap[node_id].children: + queue.append(child.id) + + result.append(current_level) + + return result + +if __name__ == "__main__": + treeInfo = { + 'adj': { + 1: [2, 3], + 2: [4, 5], + 3: [6, 7], + 4: [], + 5: [8, 9], + 6: [], + 7: [], + 8: [], + 9: [] + }, + 'root': 1, + 'position': { + 1: (400, 100), + 2: (200, 200), + 3: (600, 200), + 4: (100, 300), + 5: (300, 300), + 6: (500, 300), + 7: (700, 300), + 8: (200, 400), + 9: (400, 400) + }, + 'goals': [] + } + world = CreateTreeWorld(worldName="Leetcode Binary Tree Level Order Traversal", worldInfo=treeInfo, radius=30) + world.constructWorld() + agent = TreeAgent(world, agentName="TraversalAgent") + world.setAgent(agent) + + def sim(): + print("Starting the simulation!") + levels = levelOrderTraversal(1, agent, world) + print("Level Order Traversal:") + for level in levels: + print(level) + print("Simulation Completed!") + + agent.setAlgorithmCallBack(sim) + world.showWorld() \ No newline at end of file diff --git a/tutorials/Tree World/leetcode_lowest_common_ancestor_od_a_binary_tree.py b/tutorials/Tree World/leetcode_lowest_common_ancestor_od_a_binary_tree.py new file mode 100644 index 0000000..ab0f865 --- /dev/null +++ b/tutorials/Tree World/leetcode_lowest_common_ancestor_od_a_binary_tree.py @@ -0,0 +1,60 @@ +from traverseCraft.world import CreateTreeWorld +from traverseCraft.agent import TreeAgent + +def lowestCommonAncestor(rootId:int, p:int, q:int, agent:TreeAgent, world:CreateTreeWorld)->int: + if(rootId == None): + return None + if(rootId == p or rootId == q): + return rootId + children = [] + for child in world.nodeMap[rootId].children: + agent.moveAgent(child.id, delay=0.5) + children.append(lowestCommonAncestor(child.id, p, q, agent, world)) + agent.moveAgent(rootId, delay=0.5) + + for child in children: + if(child == None): + children.remove(child) + if(len(children) == 2): + return rootId + elif(len(children) == 1): + return children[0] + return None + +if __name__ == "__main__": + treeInfo = { + 'adj': { + 1: [2, 3], + 2: [4, 5], + 3: [6, 7], + 4: [], + 5: [8, 9], + 6: [], + 7: [], + 8: [], + 9: [] + }, + 'root': 1, + 'position': { + 1: (400, 100), + 2: (200, 200), + 3: (600, 200), + 4: (100, 300), + 5: (300, 300), + 6: (500, 300), + 7: (700, 300), + 8: (200, 400), + 9: (400, 400) + }, + 'goals': [7, 9] + } + world = CreateTreeWorld(worldName = "Leetcode Lowest Common Ancestor of a Binary Tree", worldInfo = treeInfo, radius = 30) + world.constructWorld() + agent = TreeAgent(world, agentName = "Robot") + world.setAgent(agent) + def sim(): + print("Starting the simulation!") + print("Lowest Common Ancestor of 7 and 9: ", lowestCommonAncestor(1, 7, 9, agent, world)) + print("Simulation Completed!") + agent.setAlgorithmCallBack(sim) + world.showWorld() \ No newline at end of file