diff --git a/src/l33tcode/841.hs b/src/l33tcode/841.hs index e69de29..ce9970b 100644 --- a/src/l33tcode/841.hs +++ b/src/l33tcode/841.hs @@ -0,0 +1,52 @@ +{- +Keys and Rooms + +Instructions: +There are n rooms labelled from 0 to n - 1 and all the rooms are locked except for room 0. Your goal is to visit all the rooms. However, you cannot enter a locked room without having its key. + +When you visit a room, you may find a set of distinct keys in it. Each key has a number on it, denoting which room it unlocks, and you can take all of them with you to unlock the other rooms. + +Given an array rooms where rooms[i] is the set of keys that you can obtain if you visited room i, return true if you can visit all the rooms, or false otherwise. + +Constraints: + n == rooms.length + 2 <= n <= 1000 + 0 <= rooms[i].length <= 1000 + 1 <= sum(rooms[i].length) <= 3000 + 0 <= rooms[i][j] < n + All the values of rooms[i] are unique. +-} +module Main where + +import Data.List (genericIndex, genericLength) + +input1Rooms :: [[Integer]] +input1Rooms = [[1],[2],[3],[]] + +input2Rooms :: [[Integer]] +input2Rooms = [[1,3],[3,0,1],[2],[0]] + +main :: IO () +main = do + print $ "Example 1 is: " <> show (canVisitAll input1Rooms) + print $ "Example 2 is: " <> show (canVisitAll input2Rooms) + +canVisitAll :: [[Integer]] -> Bool +canVisitAll rooms = [0..l] == dfs rooms 0 [] + where + l = l' rooms - 1 + +dfs :: [[Integer]] -> Integer -> [Integer] -> [Integer] +dfs graph current visited = + foldl (\visited next -> + if next `elem` visited + then visited + else dfs graph next visited) + (visited ++ [current]) + (graph !!! current) + +l' :: [a] -> Integer +l' = genericLength + +(!!!) :: [a] -> Integer -> a +(!!!) = genericIndex