This commit is contained in:
Jill 2022-12-13 14:30:11 +03:00
parent 299beb9c73
commit c316ce45dd
4 changed files with 122 additions and 1 deletions

52
13-a.hs Normal file
View File

@ -0,0 +1,52 @@
import Prelude
import Data.List.Split (splitOn)
import Data.Char (isNumber)
import Data.List (elemIndices)
{- cabal:
build-depends: base, split
-}
data Node = List [Node] | Num Int
deriving (Eq, Show)
compareNodes :: Node -> Node -> Ordering
-- two ints
compareNodes (Num x) (Num y) = compare x y
-- two lists
compareNodes (List []) (List []) = EQ
compareNodes (List _) (List []) = GT
compareNodes (List []) (List _) = LT
compareNodes (List (x:xs)) (List (y:ys))
| r /= EQ = r
| otherwise = compareNodes (List xs) (List ys)
where r = compareNodes x y
-- mixed
compareNodes (Num x) (List y) = compareNodes (List [Num x]) (List y)
compareNodes (List x) (Num y) = compareNodes (List x) (List [Num y])
-- "1,[2,3],4,[5,[6,7]]" -> ["1","[2,3]","4","[5,[6,7]]"]
parseList :: String -> [String]
parseList = go 0 ""
where
go :: Int -> String -> String -> [String]
go 0 "" [] = []
go 0 accum [] = [accum]
go _ _ [] = error "unclosed parens"
go depth accum (c:xs)
| c == '[' = go (depth + 1) (accum ++ [c]) xs
| c == ']' = go (depth - 1) (accum ++ [c]) xs
| c == ',' && depth == 0 = accum : go depth "" xs
| otherwise = go depth (accum ++ [c]) xs
parseNode :: String -> Node
parseNode s
| head s == '[' && last s == ']' = List $ map parseNode $ parseList (reverse $ drop 1 $ reverse $ drop 1 s)
| all isNumber s = Num $ read s
| otherwise = error s
main = interact $
show
. sum . map (+ 1) . elemIndices LT
. map ((\[a, b] -> a `compareNodes` b) . map parseNode . lines)
. splitOn "\n\n"

57
13-b.hs Normal file
View File

@ -0,0 +1,57 @@
import Prelude
import Data.List.Split (splitOn)
import Data.Char (isNumber)
import Data.List (sortBy, findIndices, intercalate)
{- cabal:
build-depends: base, split
-}
data Node = List [Node] | Num Int
deriving (Eq, Show)
compareNodes :: Node -> Node -> Ordering
-- two ints
compareNodes (Num x) (Num y) = compare x y
-- two lists
compareNodes (List []) (List []) = EQ
compareNodes (List _) (List []) = GT
compareNodes (List []) (List _) = LT
compareNodes (List (x:xs)) (List (y:ys))
| r /= EQ = r
| otherwise = compareNodes (List xs) (List ys)
where r = compareNodes x y
-- mixed
compareNodes (Num x) (List y) = compareNodes (List [Num x]) (List y)
compareNodes (List x) (Num y) = compareNodes (List x) (List [Num y])
-- "1,[2,3],4,[5,[6,7]]" -> ["1","[2,3]","4","[5,[6,7]]"]
parseList :: String -> [String]
parseList = go 0 ""
where
go :: Int -> String -> String -> [String]
go 0 "" [] = []
go 0 accum [] = [accum]
go _ _ [] = error "unclosed parens"
go depth accum (c:xs)
| c == '[' = go (depth + 1) (accum ++ [c]) xs
| c == ']' = go (depth - 1) (accum ++ [c]) xs
| c == ',' && depth == 0 = accum : go depth "" xs
| otherwise = go depth (accum ++ [c]) xs
parseNode :: String -> Node
parseNode s
| head s == '[' && last s == ']' = List $ map parseNode $ parseList (reverse $ drop 1 $ reverse $ drop 1 s)
| all isNumber s = Num $ read s
| otherwise = error s
dividerPackets = [List [List [Num 2]], List [List [Num 6]]]
main = interact $
show
. product
. map (+ 1) . findIndices (`elem` dividerPackets)
. sortBy compareNodes
. (++ dividerPackets)
. map parseNode
. filter (not . null) . lines

10
13-extra.hs Normal file
View File

@ -0,0 +1,10 @@
import Data.List (intercalate)
data Node = List [Node] | Num Int
deriving (Eq)
-- here's a Show instance for Node that recreates the input:
instance Show Node where
show (List x) = "[" ++ intercalate "," (map show x) ++ "]"
show (Num n) = show n

View File

@ -10,4 +10,6 @@ you shouldn't; but for documentation purposes it's
$ ghc 1-a.hs && cat 1_input | ./1-a
```
you'll need to retrieve `1_input` from your aoc, but all programs will strictly take in the aoc input and ~~output what can be pasted into the anwser field~~ (thanks, day 10 part 2!)
you'll need to retrieve `1_input` from your aoc, but all programs will strictly take in the aoc input and ~~output what can be pasted into the anwser field~~ (thanks, day 10 part 2!)
occasionally, i'll also leave `-extra.hs` files for misc stuff i never ended up using but was neat anyways and i wanted to preserve