never executed always true always false
    1 {-|
    2 Module:      Y2021.D16
    3 Description: Advent of Code 2021 Day 16 Solutions.
    4 License:     MIT
    5 Maintainer:  @tylerjl
    6 
    7 Solutions to the 2021 day 16 set of problems for <adventofcode.com>.
    8 -}
    9 module Y2021.D16
   10   ( parse16
   11   , part16A
   12   , part16B
   13   ) where
   14 
   15 import Control.Applicative
   16 import Data.Attoparsec.Text as P
   17 import Data.Either.Utils       (fromRight)
   18 import Data.Foldable
   19 import Data.Monoid
   20 import Data.Text               (Text)
   21 
   22 import qualified Data.Text as T
   23 import qualified GHC.Exts  as L
   24 
   25 -- |Solution to part A
   26 part16A :: Text -> Int
   27 part16A = sumVersion . parse16
   28 
   29 sumVersion :: Packet -> Int
   30 sumVersion (PacketLit v _) = v
   31 sumVersion (PacketOp v _ ps) = v + getSum (foldMap (Sum . sumVersion) ps)
   32 
   33 -- |Solution to part B
   34 part16B :: Text -> Int
   35 part16B = decodePacket . parse16
   36 
   37 decodePacket :: Packet -> Int
   38 decodePacket (PacketLit _ n) = n
   39 decodePacket (PacketOp _ 0 ps) = foldl' (\acc -> (+) acc . decodePacket) 0 ps
   40 decodePacket (PacketOp _ 1 ps) = foldl' (\acc -> (*) acc . decodePacket) 1 ps
   41 decodePacket (PacketOp _ 2 ps) = minimum (map decodePacket ps)
   42 decodePacket (PacketOp _ 3 ps) = maximum (map decodePacket ps)
   43 decodePacket (PacketOp _ 5 [p1, p2])
   44   | decodePacket p1 > decodePacket p2 = 1
   45   | otherwise = 0
   46 decodePacket (PacketOp _ 6 [p1, p2])
   47   | decodePacket p1 < decodePacket p2 = 1
   48   | otherwise = 0
   49 decodePacket (PacketOp _ 7 [p1, p2])
   50   | decodePacket p1 == decodePacket p2 = 1
   51   | otherwise = 0
   52 decodePacket PacketOp {} = error "unknown operator packet"
   53 
   54 type Version = Int
   55 type PType = Int
   56 data Packet
   57   = PacketLit Version Int
   58   | PacketOp Version PType [Packet]
   59   deriving Show
   60 
   61 -- |Parse.
   62 parse16 :: Text -> Packet
   63 parse16 = fromRight . parseOnly parser . hexToBin
   64   where
   65     parser = packet <* atEnd
   66     packet = packetLit <|> packetOp
   67 
   68     packetLit = PacketLit <$> bitN 3 <* string "100" <*> (asInt . concat <$> litNumber)
   69     litNumber = litQuad
   70     litQuad = mappend <$> many litInit <*> ((: []) <$> litTail)
   71     litInit = char '1' *> count 4 bit
   72     litTail = char '0' *> count 4 bit
   73 
   74     packetOp = PacketOp <$> bitN 3 <*> bitN 3 <*> (lenPacket <|> numPacket)
   75     lenPacket = do
   76       _ <- char '0'
   77       len <- bitN 15
   78       parseOf (P.take len) (many1 packet)
   79     numPacket = do
   80       _ <- char '1'
   81       packets <- bitN 11
   82       count packets packet
   83 
   84     bitN n = asInt <$> count n bit
   85     asInt = convert . reverse
   86     bit = read . (: []) <$> binary
   87     binary = char '0' <|> char '1'
   88 
   89 constP :: Parser a -> Text -> Parser a
   90 constP p t = case parseOnly p t of
   91   Left _ -> empty
   92   Right a -> return a
   93 
   94 parseOf :: Parser Text -> Parser a -> Parser a
   95 parseOf ptxt pa = bothParse
   96   where
   97     bothParse = ptxt >>= constP pa
   98 
   99 hexToBin :: Text -> Text
  100 hexToBin = T.concat . map hexToBits  . L.toList
  101 
  102 convert :: [Int] -> Int
  103 convert [] = 0
  104 convert (x : xs) = x + 2 * convert xs
  105 
  106 hexToBits :: Char -> Text
  107 hexToBits '0' = "0000"
  108 hexToBits '1' = "0001"
  109 hexToBits '2' = "0010"
  110 hexToBits '3' = "0011"
  111 hexToBits '4' = "0100"
  112 hexToBits '5' = "0101"
  113 hexToBits '6' = "0110"
  114 hexToBits '7' = "0111"
  115 hexToBits '8' = "1000"
  116 hexToBits '9' = "1001"
  117 hexToBits 'A' = "1010"
  118 hexToBits 'B' = "1011"
  119 hexToBits 'C' = "1100"
  120 hexToBits 'D' = "1101"
  121 hexToBits 'E' = "1110"
  122 hexToBits 'F' = "1111"
  123 hexToBits _ = ""