X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=advent16%2FMain.hs;h=98e7879a9db98df04f4835d57e5610814a944b40;hb=4506b761e9bc00ea63e0dbc93f6b619b02895e15;hp=d9fc4a67c843656f888e85286dc129c8aa68cce7;hpb=4437cd7086d710333d3667ec59be74a57bdff76e;p=advent-of-code-21.git diff --git a/advent16/Main.hs b/advent16/Main.hs index d9fc4a6..98e7879 100644 --- a/advent16/Main.hs +++ b/advent16/Main.hs @@ -1,11 +1,12 @@ --- 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 import Data.Char import Data.Int -import Control.Monad.State.Lazy +-- import Control.Monad.State.Lazy +import Control.Monad.State.Strict import qualified Data.ByteString as BYS import qualified Data.Bitstream as BS @@ -55,23 +56,34 @@ getBool :: ParseTrans Bool 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 @@ -81,38 +93,8 @@ getLiteralAcc acc = 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 = @@ -137,6 +119,17 @@ getPacketsByCount n = 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)