Skip to content

Instantly share code, notes, and snippets.

@franksacco
Created May 7, 2019 14:40
Show Gist options
  • Save franksacco/2ebba093c3669e15c8959db94312bf22 to your computer and use it in GitHub Desktop.
Save franksacco/2ebba093c3669e15c8959db94312bf22 to your computer and use it in GitHub Desktop.
--
-- Skyscrapers: game solution checker
--
import Data.List
import System.IO
-- Read matrix values from a string
read_matrix :: String -> [[Int]]
read_matrix c = map (map read) (map words $ lines c)
-- Counts the number of visible rooftops in the given list using left folding
rooftops :: [Int] -> Int
rooftops xs = snd $ foldl (\(m,n) x -> if x > m then (x,n+1) else (m,n)) (0,0) xs
-- Checks if the constraints in the border are satisfied
check_constraints :: [[Int]] -> Bool
check_constraints [[]] = False
check_constraints m = and $
map (check_row_constraints . init) (tail $ init m) ++ -- from left to right
map (check_row_constraints . reverse . tail) (tail $ init m) ++ -- from right to left
map (check_row_constraints . init) (tail $ init $ transpose m) ++ -- from top to down
map (check_row_constraints . reverse . tail) (tail $ init $ transpose m) -- from down to top
check_row_constraints :: [Int] -> Bool
check_row_constraints [] = False
check_row_constraints (n:v) = n == 0 || n == rooftops v
-- Checks if values in matrix are in the correct range and unique for each row and column
check_values :: [[Int]] -> Bool
check_values [[]] = False
check_values m = and $ map (check_row_values . tail . init) (tail $ init m)
check_row_values :: [Int] -> Bool
check_row_values r = sort r == [1..(length r)]
-- Checks if matrix solution provided is correct
check :: [[Int]] -> IO ()
check [[]] = putStrLn "Error: empty matrix!"
check m
| check_values m && check_constraints m = putStrLn "Your solution is correct!"
| otherwise = putStrLn "Your solution is not correct. Try again."
main = do
file <- readFile "game5x5.txt"
check $ read_matrix file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment