47 lines
1.9 KiB
Haskell
47 lines
1.9 KiB
Haskell
module Commons where
|
|
|
|
import GHC.IO.Handle (isEOF)
|
|
import Data.Array (Array, listArray, (!), indices)
|
|
import Data.List.Unique (sortUniq)
|
|
|
|
|
|
type Image = [(Int, Int)]
|
|
type ExpansionArray = Array Int Int
|
|
|
|
|
|
parseLine :: Int -> Int -> String -> Image
|
|
parseLine _ _ [] = []
|
|
parseLine row column ('#': t) = (column, row): parseLine row (column + 1) t
|
|
parseLine row column (_: t) = parseLine row (column + 1) t
|
|
|
|
parseImage :: Int -> Image -> IO Image
|
|
parseImage row image = do done <- isEOF
|
|
if done
|
|
then return image
|
|
else do line <- getLine
|
|
parseImage (row + 1) (image ++ parseLine row 1 line)
|
|
|
|
parse :: IO Image
|
|
parse = parseImage 1 []
|
|
|
|
|
|
getExpansionArray :: Int -> Int -> Int -> [Int] -> [Int]
|
|
getExpansionArray _ _ _ [] = []
|
|
getExpansionArray i expOffset expInc (h: t)
|
|
| i == h = i + expOffset: getExpansionArray (i + 1) expOffset expInc t
|
|
| i < h = i + expOffset: getExpansionArray (i + 1) (expOffset + expInc) expInc (h: t)
|
|
|
|
getExpansionArrays :: Int -> Image -> (ExpansionArray, ExpansionArray)
|
|
getExpansionArrays expInc image = let expX = getExpansionArray 1 0 expInc $ sortUniq . map fst $ image
|
|
expY = getExpansionArray 1 0 expInc $ sortUniq . map snd $ image
|
|
in (listArray (1, length expX) expX, listArray (1, length expY) expY)
|
|
|
|
getDistancesGalaxy :: Image -> (ExpansionArray, ExpansionArray) -> (Int, Int) -> [Int]
|
|
getDistancesGalaxy [] _ _ = []
|
|
getDistancesGalaxy ((x0, y0): t) (expX, expY) (x1, y1) =
|
|
abs ((expX ! x0) - (expX ! x1)) + abs ((expY ! y0) - (expY ! y1)): getDistancesGalaxy t (expX, expY) (x1, y1)
|
|
|
|
getDistances :: Image -> (ExpansionArray, ExpansionArray) -> [[Int]]
|
|
getDistances [] _ = []
|
|
getDistances (h: t) (expX, expY) = getDistancesGalaxy t (expX, expY) h: getDistances t (expX, expY)
|