|
|
|
@ -8,7 +8,6 @@ module Day13Lib
|
|
|
|
|
)
|
|
|
|
|
where
|
|
|
|
|
|
|
|
|
|
-- import Data.Either
|
|
|
|
|
import Data.List
|
|
|
|
|
import Data.List.Split (splitOn)
|
|
|
|
|
import Debug.Trace
|
|
|
|
@ -16,6 +15,17 @@ import Text.Parsec
|
|
|
|
|
|
|
|
|
|
data Value = Num Int | List [Value] deriving (Show, Eq)
|
|
|
|
|
|
|
|
|
|
instance Ord Value where
|
|
|
|
|
compare (Num x) (Num y) = compare x y
|
|
|
|
|
compare x@(Num _) y@(List _) = compare (List [x]) y
|
|
|
|
|
compare x@(List _) y@(Num _) = compare x (List [y])
|
|
|
|
|
compare (List (x : xs)) (List (y : ys)) = case compare x y of
|
|
|
|
|
EQ -> compare (List xs) (List ys)
|
|
|
|
|
o -> o
|
|
|
|
|
compare (List []) (List (y : ys)) = LT
|
|
|
|
|
compare (List (x : xs)) (List []) = GT
|
|
|
|
|
compare (List []) (List []) = EQ
|
|
|
|
|
|
|
|
|
|
parseList :: Parsec String () Value
|
|
|
|
|
parseList = do
|
|
|
|
|
char '['
|
|
|
|
@ -28,17 +38,6 @@ parseNumber = do
|
|
|
|
|
ns <- try . many1 $ digit
|
|
|
|
|
return $ Num (read ns)
|
|
|
|
|
|
|
|
|
|
cmp :: Value -> Value -> Ordering
|
|
|
|
|
cmp (Num x) (Num y) = compare x y
|
|
|
|
|
cmp x@(Num _) y@(List _) = cmp (List [x]) y
|
|
|
|
|
cmp x@(List _) y@(Num _) = cmp x (List [y])
|
|
|
|
|
cmp (List (x : xs)) (List (y : ys)) = case cmp x y of
|
|
|
|
|
EQ -> cmp (List xs) (List ys)
|
|
|
|
|
o -> o
|
|
|
|
|
cmp (List []) (List (y : ys)) = LT
|
|
|
|
|
cmp (List (x : xs)) (List []) = GT
|
|
|
|
|
cmp (List []) (List []) = EQ
|
|
|
|
|
|
|
|
|
|
runParse :: String -> Value
|
|
|
|
|
runParse s = case parse parseList "" s of
|
|
|
|
|
Left e -> error $ "parse error: " ++ show e
|
|
|
|
@ -49,19 +48,16 @@ runParse s = case parse parseList "" s of
|
|
|
|
|
processInput1 :: String -> Int
|
|
|
|
|
processInput1 =
|
|
|
|
|
sum
|
|
|
|
|
. zipWith (\x y -> if y == LT then x else 0) [1 ..]
|
|
|
|
|
. zipWith (\x [v1, v2] -> if v1 < v2 then x else 0) [1 ..]
|
|
|
|
|
. map
|
|
|
|
|
( (\[x, y] -> cmp x y)
|
|
|
|
|
. map runParse
|
|
|
|
|
. lines
|
|
|
|
|
)
|
|
|
|
|
(map runParse . lines)
|
|
|
|
|
. splitOn "\n\n"
|
|
|
|
|
|
|
|
|
|
processInput2 :: String -> Int
|
|
|
|
|
processInput2 =
|
|
|
|
|
product
|
|
|
|
|
. zipWith (\x y -> if y `elem` dividers then x else 1) [1 ..]
|
|
|
|
|
. sortBy cmp
|
|
|
|
|
. sort
|
|
|
|
|
. (++) dividers
|
|
|
|
|
. (concatMap (map runParse . lines) . splitOn "\n\n")
|
|
|
|
|
|
|
|
|
|