|
| 1 | +import Data.List |
| 2 | +import System.Environment (getArgs) |
| 3 | + |
| 4 | +type Mirror = ([String], [String]) |
| 5 | + |
| 6 | +main = do |
| 7 | + args <- getArgs |
| 8 | + input <- readFile (args !! 0) |
| 9 | + let mirrors = parse (lines input) |
| 10 | + |
| 11 | + print(answer1 mirrors) |
| 12 | + |
| 13 | +-- Answer 1. |
| 14 | + |
| 15 | +answer1 :: [Mirror] -> Int |
| 16 | +answer1 ms = foldl (+) 0 [contribution (m1, m2) | (m1, m2) <- ms] |
| 17 | + |
| 18 | +contribution (m1, m2) = case (symmetryLine m1, symmetryLine m2) of |
| 19 | + (Just n, Nothing) -> 100 * (n + 1) |
| 20 | + (Nothing, Just n) -> (n + 1) |
| 21 | + |
| 22 | +symmetryLine :: [String] -> Maybe Int |
| 23 | +symmetryLine strs = find (isSymmetry strs) [0..(length strs)-2] |
| 24 | + |
| 25 | +isSymmetry :: [String] -> Int -> Bool |
| 26 | +isSymmetry strs n = (take smallest before) == (take smallest after) |
| 27 | + where |
| 28 | + before = [strs !! i | i <- reverse [0..n]] |
| 29 | + after = [strs !! i | i <- [n + 1..(length strs) - 1]] |
| 30 | + smallest = min (length before) (length after) |
| 31 | + |
| 32 | +-- Answer 2. |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | +-- Parse input. |
| 37 | + |
| 38 | +parse :: [String] -> [Mirror] |
| 39 | +parse strs = [(n, rotateNote n) | n <- parseNotes [] [] strs] |
| 40 | + |
| 41 | +parseNotes :: [[String]] -> [String] -> [String] -> [[String]] |
| 42 | +parseNotes acc note [] = acc ++ [note] |
| 43 | +parseNotes acc note (s : strs) |
| 44 | + | null s = parseNotes (acc ++ [note]) [] strs |
| 45 | + | otherwise = parseNotes acc (note ++ [s]) strs |
| 46 | + |
| 47 | +rotateNote :: [String] -> [String] |
| 48 | +rotateNote strs = [col x | x <- [0..xSz-1]] |
| 49 | + where |
| 50 | + (xSz, ySz) = (length (strs !! 0), length strs) |
| 51 | + at x y = (strs !! y) !! x |
| 52 | + col x = [ at x y | y <- [0..ySz-1]] |
0 commit comments