From: Neil Smith Date: Sun, 19 Dec 2021 10:05:49 +0000 (+0000) Subject: Reordered bits X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=c165c3ab1c58c85f8de4653a91379158ecc91d53;p=advent-of-code-21.git Reordered bits --- diff --git a/advent16/Main.hs b/advent16/Main.hs index d9fc4a6..ab14272 100644 --- a/advent16/Main.hs +++ b/advent16/Main.hs @@ -1,4 +1,4 @@ --- 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 @@ -55,23 +55,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 +92,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 +118,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)