{- 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