--- Writeup at https://work.njae.me.uk/2021/12/16/advent-of-code-2021-day-14/
+-- Writeup at https://work.njae.me.uk/2021/12/18/advent-of-code-2021-day-16/
import Data.Word
import Data.Bits
getBool =
do bs <- get
let value = head $ BS.unpack $ BS.take 1 bs
- put (BS.drop 1 bs)
+ put $ BS.drop 1 bs
return value
getInt :: Int64 -> ParseTrans Integer
getInt n =
do bs <- get
let value = BS.toBits $ BS.take n bs
- put (BS.drop n bs)
+ put $ BS.drop n bs
return value
getBits :: Int64 -> ParseTrans Transmission
getBits n =
do bs <- get
let bits = BS.take n bs
- put (BS.drop n bs)
+ put $ BS.drop n bs
return bits
+getPacket :: ParseTrans Packet
+getPacket =
+ do version <- getInt 3
+ pType <- getInt 3
+ payload <- if pType == 4
+ then do val <- getLiteral
+ return $ Literal val
+ else do contents <- getOperatorContents
+ return $ mkOperator pType contents
+ return $ Packet version payload
+
getLiteral :: ParseTrans Integer
getLiteral = getLiteralAcc 0
nybble <- getInt 4
let acc' = acc * 16 + nybble
if continues
- then (do getLiteralAcc acc')
- else (return acc')
-
--- getLiteralPacket :: ParseTrans (Integer, Integer, Integer)
--- getLiteralPacket =
--- do version <- getInt 3
--- pType <- getInt 3
--- val <- getLiteral
--- return (version, pType, val)
-
-
-getPacket :: ParseTrans Packet
-getPacket =
- do version <- getInt 3
- pType <- getInt 3
- payload <- case pType of
- 4 -> do val <- getLiteral
- return $ Literal val
- _ -> do contents <- getOperatorContents
- return $ mkOperator pType contents
- return $ Packet version payload
-
-mkOperator :: Integer -> [Packet] -> PacketContents
-mkOperator pType contents = case pType of
- 0 -> Sum contents
- 1 -> Product contents
- 2 -> Minimum contents
- 3 -> Maximum contents
- 5 -> GreaterThan (contents!!0) (contents!!1)
- 6 -> LessThan (contents!!0) (contents!!1)
- 7 -> EqualTo (contents!!0) (contents!!1)
-
+ then do getLiteralAcc acc'
+ else return acc'
getOperatorContents :: ParseTrans [Packet]
getOperatorContents =
ps <- getPacketsByCount (n - 1)
return (p : ps)
+mkOperator :: Integer -> [Packet] -> PacketContents
+mkOperator pType contents = case pType of
+ 0 -> Sum contents
+ 1 -> Product contents
+ 2 -> Minimum contents
+ 3 -> Maximum contents
+ 5 -> GreaterThan (contents!!0) (contents!!1)
+ 6 -> LessThan (contents!!0) (contents!!1)
+ 7 -> EqualTo (contents!!0) (contents!!1)
+
+
packetVersionSum :: Packet -> Integer
packetVersionSum (Packet version contents) =
version + (contentsVersionSum contents)