|
1 | 1 | module Recursion where
|
2 | 2 |
|
3 | 3 | import Basics (Nat)
|
4 | | - |
| 4 | +importTree (findAllPaths) |
5 | 5 |
|
6 | 6 | {-
|
7 | 7 | Recursion: the program call itself
|
@@ -53,7 +53,7 @@ countWaysMemo n = countWaysData!!n
|
53 | 53 | countWaysDataHelper :: Nat -> Nat-> [Nat] -> [Nat]
|
54 | 54 | countWaysDataHelper i n countData
|
55 | 55 | | i+2 == n = countData
|
56 | | - | otherwise = countWaysDataHelper (i+1) n (countData ++ |
| 56 | + | otherwise = countWaysDataHelper (i+1) n (countData ++ |
57 | 57 | [countData!!i + countData!!(i+1) + countData!!(i+2)])
|
58 | 58 |
|
59 | 59 | {-
|
@@ -88,3 +88,82 @@ permutateSeq :: [[Nat]] -> [Nat] -> [[Nat]]
|
88 | 88 | permutateSeq existSeq [] = []
|
89 | 89 | permutateSeq existSeq (x:xs) = map (++ [x]) existSeq ++
|
90 | 90 | permutateSeq existSeq xs
|
| 91 | + |
| 92 | +{- |
| 93 | + 8.2 |
| 94 | + Imagine a robot sitting on the upper left corner of grid with r rows |
| 95 | + and c columns. The robot can only move in two directions, right and |
| 96 | + down, but certain cells are "off limits" such that the robot cannot |
| 97 | + step on them. Design an algorithm to find a path for the robot from |
| 98 | + the top left to the bottom right. |
| 99 | + |
| 100 | + Let assume the start point is (0,0), the a normal x-axis, but a |
| 101 | + opposite y-axis (the bottom half is positive), each time we either move |
| 102 | + right or move down, this mean each time, we increase (x,y) either x or y |
| 103 | + by one until we reach to (c, r) |
| 104 | + |
| 105 | + Theoretically, it has 2^(c+r) different paths |
| 106 | + |
| 107 | + test case: allPaths (0,0) (3,3) [(1,2), (3,2)] |
| 108 | +-} |
| 109 | + |
| 110 | +{- |
| 111 | + Find the next possible move |
| 112 | + |
| 113 | + (x, y): current position |
| 114 | + (c, r): final position |
| 115 | + constrs: cells are not available (can't include the start cell) |
| 116 | +-} |
| 117 | +move :: (Nat, Nat) -> (Nat, Nat) -> [(Nat, Nat)]-> [Maybe (Nat, Nat)] |
| 118 | +move (x, y) (c, r) constrs |
| 119 | + | x+1 <= c && y+1 <= r && xCell `notElem` constrs && yCell `notElem` constrs = |
| 120 | + [Just xCell, Just yCell] |
| 121 | + | x+1 <= c && y+1 <= r && xCell `elem` constrs && yCell `notElem` constrs = |
| 122 | + [Nothing, Just yCell] |
| 123 | + | x+1 <= c && y+1 <= r && xCell `notElem` constrs && yCell `elem` constrs = |
| 124 | + [Just xCell, Nothing] |
| 125 | + | x+1 <= c && y+1 <= r && xCell `elem` constrs && yCell `elem` constrs = |
| 126 | + [Nothing, Nothing] |
| 127 | + | x+1 > c && y+1 <= r && yCell `notElem` constrs = |
| 128 | + [Nothing, Just yCell] |
| 129 | + | x+1 <= c && y+1 > r && xCell `notElem` constrs = |
| 130 | + [Just xCell, Nothing] |
| 131 | + | otherwise = [Nothing, Nothing] |
| 132 | + where xCell = (x+1, y) |
| 133 | + yCell = (x, y+1) |
| 134 | + |
| 135 | +-- Check whether the cell is valid |
| 136 | +isValidCell :: [(Nat, Nat)] -> [(Nat, Nat)] -> Bool |
| 137 | +isValidCell [] _ = True |
| 138 | +isValidCell _ [] = True |
| 139 | +isValidCell (x:xs) constrs = (x `notElem` constrs) && isValidCell xs constrs |
| 140 | + |
| 141 | +-- Create a heap to record all possible sequence |
| 142 | +allPathsHelper :: |
| 143 | + [Maybe (Nat, Nat)] -> (Nat, Nat) -> [(Nat, Nat)]-> [Maybe(Nat, Nat)] |
| 144 | +allPathsHelper [] _ _ = [] |
| 145 | +allPathsHelper (Nothing:xs) final constrs |
| 146 | + -- end infinite nothing loop |
| 147 | + | all (== Nothing) (Nothing:xs) = [] |
| 148 | + | otherwise = nothingMoves ++ allPathsHelper (xs++nothingMoves) final constrs |
| 149 | + where nothingMoves = [Nothing, Nothing] |
| 150 | +allPathsHelper (Just (x, y):xs) final constrs = |
| 151 | + nextMoves ++ allPathsHelper (xs++nextMoves) final constrs |
| 152 | + where nextMoves = move (x,y) final constrs |
| 153 | + |
| 154 | +-- Return the Completed Heap |
| 155 | +allPaths :: (Nat, Nat) -> (Nat, Nat) -> [(Nat, Nat)] -> [Maybe(Nat, Nat)] |
| 156 | +allPaths start end constrs = |
| 157 | + Just start: removeNothing (allPathsHelper [Just start] end constrs) |
| 158 | + |
| 159 | +-- Return all unique paths index in a Heap |
| 160 | +allPaths' :: (Nat, Nat) -> (Nat, Nat) -> [(Nat, Nat)] -> [[Nat]] |
| 161 | +allPaths' start end constrs = findAllPaths completedHeap [] (length completedHeap-1) |
| 162 | + where completedHeap = |
| 163 | + Just start: removeNothing (allPathsHelper [Just start] end constrs) |
| 164 | + |
| 165 | +-- Remove Nothing on the tail |
| 166 | +removeNothing :: [Maybe(Nat, Nat)] -> [Maybe(Nat, Nat)] |
| 167 | +removeNothing xs |
| 168 | + | xs!!(length xs -1) == Nothing = removeNothing $ init xs |
| 169 | + | otherwise = xs |
0 commit comments