days 11-15
This commit is contained in:
73
src/Days/Day13.hs
Normal file
73
src/Days/Day13.hs
Normal file
@@ -0,0 +1,73 @@
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
|
||||
module Days.Day13 where
|
||||
|
||||
import AOCUtil
|
||||
import Data.Bool
|
||||
import Data.Char
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Debug.Trace
|
||||
import GHC.Arr
|
||||
import GHC.Utils.Misc
|
||||
|
||||
runA :: IO ()
|
||||
runA = interactF "data/day13.txt" solve
|
||||
|
||||
runB :: IO ()
|
||||
runB = interactF "data/day13.txt" solveB
|
||||
|
||||
solve :: String -> String
|
||||
solve = show . sum . map fst . filter ((== LT) . snd) . zip [1 ..] . map (uncurry cmpE . first2 . map parseElement) . splitOn "" . lines
|
||||
|
||||
solveB :: String -> String
|
||||
solveB = show . product . map fst . filter ((`elem` dividers) . snd) . zip [1 ..] . sortBy cmpE . (++ dividers) . map parseElement . filter (/= "") . lines
|
||||
|
||||
data Element = I Int | E [Element] deriving (Eq)
|
||||
|
||||
instance Show Element where
|
||||
show (I i) = show i
|
||||
show (E ls) = show ls
|
||||
|
||||
dividers :: [Element]
|
||||
dividers = [E [E [I 2]], E [E [I 6]]]
|
||||
|
||||
cmpE :: Element -> Element -> Ordering
|
||||
cmpE (I i) (I j) = compare i j
|
||||
cmpE (E ls) (E ms) = fromMaybe EQ . listToMaybe . dropWhile (== EQ) . (++ [length ls `compare` length ms]) . zipWith cmpE ls $ ms
|
||||
cmpE (E ls) (I j) = cmpE (E ls) (E [I j])
|
||||
cmpE (I i) (E ms) = cmpE (E [I i]) (E ms)
|
||||
|
||||
parseElement :: String -> Element
|
||||
parseElement s
|
||||
| isDigit (head s) = I . read $ s
|
||||
| (== '[') . head $ s = E . map parseElement . splitBlocks . tail . init $ s
|
||||
|
||||
splitBlocks :: String -> [String]
|
||||
splitBlocks = filter (not . null) . splitBlocks' 0 ""
|
||||
|
||||
splitBlocks' :: Int -> String -> String -> [String]
|
||||
splitBlocks' l p [] = [p]
|
||||
splitBlocks' l prev (s : ss)
|
||||
| l /= 0 && s == '[' = splitBlocks' (l + 1) (prev ++ [s]) ss -- levle up
|
||||
| l /= 0 && s == ']' = splitBlocks' (l - 1) (prev ++ [s]) ss -- level down
|
||||
| s == '[' = prev : splitBlocks' (l + 1) [s] ss -- levle up
|
||||
| s == ']' = prev : splitBlocks' (l - 1) [] ss -- level down
|
||||
| l /= 0 = splitBlocks' l (prev ++ [s]) ss
|
||||
| s == ',' = prev : splitBlocks' l [] ss
|
||||
| otherwise = splitBlocks' l (prev ++ [s]) ss
|
||||
|
||||
-- newtype Parser a = P {parse :: String -> (String, Maybe a)}
|
||||
|
||||
-- instance Functor Parser where
|
||||
-- fmap f (P st) = P $ \stream -> case st stream of
|
||||
-- (res, Nothing) -> (res, Nothing)
|
||||
-- (res, Just a) -> (res, Just (f a))
|
||||
|
||||
-- instance Applicative Parser where
|
||||
-- pure a = P (\stream -> (stream, Just a))
|
||||
-- P ff <*> P xx = P $ \stream0 -> case ff stream0 of
|
||||
-- (stream1, Nothing) -> (stream1, Nothing)
|
||||
-- (stream1, Just f) -> case xx stream1 of
|
||||
-- (stream2, Nothing) -> (stream2, Nothing)
|
||||
-- (stream2, Just x) -> (stream2, Just (f x))
|
||||
Reference in New Issue
Block a user