--- /dev/null
+-- Writeup at https://work.njae.me.uk/2021/12/16/advent-of-code-2021-day-14/
+
+import Data.Word
+import Data.Bits
+import Data.Char
+import Data.List
+import Data.Int
+
+import Control.Monad.State.Lazy
+
+import qualified Data.ByteString as BYS
+import qualified Data.BitString.BigEndian as BS
+-- import Data.Binary.Strict.Get
+
+type ParseState = BS.BitString
+
+data Packet = Packet Integer PacketContents
+ deriving (Show, Eq)
+
+data PacketContents
+ = Literal Integer
+ -- | Operator [Packet]
+ | Sum [Packet]
+ | Product [Packet]
+ | Minimum [Packet]
+ | Maximum [Packet]
+ | GreaterThan Packet Packet
+ | LessThan Packet Packet
+ | EqualTo Packet Packet
+ deriving (Show, Eq)
+
+main :: IO ()
+main =
+ do text <- readFile "data/advent16.txt"
+ let packetStream = bitify text
+ let (packet, _remaining) = runState getPacket packetStream
+ print $ part1 packet
+ print $ part2 packet
+
+part1 :: Packet -> Integer
+part1 = packetVersionSum
+
+part2 :: Packet -> Integer
+part2 = evaluatePacket
+
+bitify :: String -> BS.BitString
+bitify = BS.bitString . BYS.pack . hexPack . map (fromIntegral . digitToInt)
+-- byteify = BYS.pack . hexPack . map (fromIntegral . digitToInt)
+
+hexPack :: [Word8] -> [Word8]
+hexPack [] = []
+hexPack (x:[]) = hexPack [x, 0]
+hexPack (x:y:xs) = ((x `shift` 4) .|. y) : hexPack xs
+
+wordify :: BS.BitString -> Integer
+wordify bs = foldl' addBit 0 $ BS.to01List bs
+ where addBit w b = (w * 2) + (fromIntegral b)
+
+
+getBool :: State ParseState Bool
+getBool =
+ do bs <- get
+ let value = head $ BS.toList $ BS.take 1 bs
+ put (BS.drop 1 bs)
+ return value
+
+getInt :: Int64 -> State ParseState Integer
+getInt n =
+ do bs <- get
+ let bits = BS.take n bs
+ put (BS.drop n bs)
+ return (wordify bits)
+
+getBits :: Int64 -> State ParseState BS.BitString
+getBits n =
+ do bs <- get
+ let bits = BS.take n bs
+ put (BS.drop n bs)
+ return bits
+
+getLiteral :: State ParseState Integer
+getLiteral = getLiteralAcc 0
+
+getLiteralAcc :: Integer -> State ParseState Integer
+getLiteralAcc acc =
+ do continues <- getBool
+ nybble <- getInt 4
+ let acc' = acc * 16 + nybble
+ if continues
+ then (do getLiteralAcc acc')
+ else (return acc')
+
+-- getLiteralPacket :: State ParseState (Integer, Integer, Integer)
+-- getLiteralPacket =
+-- do version <- getInt 3
+-- pType <- getInt 3
+-- val <- getLiteral
+-- return (version, pType, val)
+
+
+getPacket :: State ParseState 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)
+
+
+getOperatorContents :: State ParseState [Packet]
+getOperatorContents =
+ do isNumPackets <- getBool
+ if isNumPackets
+ then do numPackets <- getInt 11
+ getPacketsByCount numPackets
+ else do numBits <- getInt 15
+ subString <- getBits (fromIntegral numBits)
+ return $ getPacketsByLength subString
+
+getPacketsByLength :: BS.BitString -> [Packet]
+getPacketsByLength bits
+ | BS.null bits = []
+ | otherwise = p : (getPacketsByLength remaining)
+ where (p, remaining) = runState getPacket bits
+
+getPacketsByCount :: Integer -> State ParseState [Packet]
+getPacketsByCount 0 = return []
+getPacketsByCount n =
+ do p <- getPacket
+ ps <- getPacketsByCount (n - 1)
+ return (p : ps)
+
+packetVersionSum :: Packet -> Integer
+packetVersionSum (Packet version contents) =
+ version + (contentsVersionSum contents)
+
+contentsVersionSum :: PacketContents -> Integer
+contentsVersionSum (Sum packets) = sum $ map packetVersionSum packets
+contentsVersionSum (Product packets) = sum $ map packetVersionSum packets
+contentsVersionSum (Minimum packets) = sum $ map packetVersionSum packets
+contentsVersionSum (Maximum packets) = sum $ map packetVersionSum packets
+contentsVersionSum (Literal _) = 0
+contentsVersionSum (GreaterThan packet1 packet2) =
+ (packetVersionSum packet1) + (packetVersionSum packet2)
+contentsVersionSum (LessThan packet1 packet2) =
+ (packetVersionSum packet1) + (packetVersionSum packet2)
+contentsVersionSum (EqualTo packet1 packet2) =
+ (packetVersionSum packet1) + (packetVersionSum packet2)
+
+evaluatePacket :: Packet -> Integer
+evaluatePacket (Packet _version contents) = evaluateContents contents
+
+evaluateContents :: PacketContents -> Integer
+evaluateContents (Sum packets) = sum $ map evaluatePacket packets
+evaluateContents (Product packets) = product $ map evaluatePacket packets
+evaluateContents (Minimum packets) = minimum $ map evaluatePacket packets
+evaluateContents (Maximum packets) = maximum $ map evaluatePacket packets
+evaluateContents (Literal n) = n
+evaluateContents (GreaterThan packet1 packet2) =
+ if (evaluatePacket packet1) > (evaluatePacket packet2) then 1 else 0
+evaluateContents (LessThan packet1 packet2) =
+ if (evaluatePacket packet1) < (evaluatePacket packet2) then 1 else 0
+evaluateContents (EqualTo packet1 packet2) =
+ if (evaluatePacket packet1) == (evaluatePacket packet2) then 1 else 0
--- /dev/null
+<!DOCTYPE html>
+<html lang="en-us">
+<head>
+<meta charset="utf-8"/>
+<title>Day 16 - Advent of Code 2021</title>
+<!--[if lt IE 9]><script src="/static/html5.js"></script><![endif]-->
+<link href='//fonts.googleapis.com/css?family=Source+Code+Pro:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'/>
+<link rel="stylesheet" type="text/css" href="/static/style.css?26"/>
+<link rel="stylesheet alternate" type="text/css" href="/static/highcontrast.css?0" title="High Contrast"/>
+<link rel="shortcut icon" href="/favicon.png"/>
+</head><!--
+
+
+
+
+Oh, hello! Funny seeing you here.
+
+I appreciate your enthusiasm, but you aren't going to find much down here.
+There certainly aren't clues to any of the puzzles. The best surprises don't
+even appear in the source until you unlock them for real.
+
+Please be careful with automated requests; I'm not a massive company, and I can
+only take so much traffic. Please be considerate so that everyone gets to play.
+
+If you're curious about how Advent of Code works, it's running on some custom
+Perl code. Other than a few integrations (auth, analytics, social media), I
+built the whole thing myself, including the design, animations, prose, and all
+of the puzzles.
+
+The puzzles are most of the work; preparing a new calendar and a new set of
+puzzles each year takes all of my free time for 4-5 months. A lot of effort
+went into building this thing - I hope you're enjoying playing it as much as I
+enjoyed making it for you!
+
+If you'd like to hang out, I'm @ericwastl on Twitter.
+
+- Eric Wastl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-->
+<body>
+<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2021/about">[About]</a></li><li><a href="/2021/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2021/settings">[Settings]</a></li><li><a href="/2021/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2021/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">32*</span></div></div><div><h1 class="title-event"> <span class="title-event-wrap">sub y{</span><a href="/2021">2021</a><span class="title-event-wrap">}</span></h1><nav><ul><li><a href="/2021">[Calendar]</a></li><li><a href="/2021/support">[AoC++]</a></li><li><a href="/2021/sponsors">[Sponsors]</a></li><li><a href="/2021/leaderboard">[Leaderboard]</a></li><li><a href="/2021/stats">[Stats]</a></li></ul></nav></div></header>
+
+<div id="sidebar">
+<div id="sponsor"><div class="quiet">Our <a href="/2021/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://ramp.com/?utm_source=advent-of-code" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">Ramp</a> - Have you ever sped up a real-world job 5x using software? Ramp does that for companies every day with financial automation. We're hiring ambitious engineers (Python, Elixir, Typescript) - join us if you like fast growth!</div></div>
+</div><!--/sidebar-->
+
+<main>
+<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
+<article class="day-desc"><h2>--- Day 16: Packet Decoder ---</h2><p>As you leave the cave and reach open waters, you receive a transmission from the Elves back on the ship.</p>
+<p>The transmission was sent using the Buoyancy Interchange Transmission System (<span title="Just be glad it wasn't sent using the BuoyancY Transmission Encoding System.">BITS</span>), a method of packing numeric expressions into a binary sequence. Your submarine's computer has saved the transmission in <a href="https://en.wikipedia.org/wiki/Hexadecimal" target="_blank">hexadecimal</a> (your puzzle input).</p>
+<p>The first step of decoding the message is to convert the hexadecimal representation into binary. Each character of hexadecimal corresponds to four bits of binary data:</p>
+<pre><code>0 = 0000
+1 = 0001
+2 = 0010
+3 = 0011
+4 = 0100
+5 = 0101
+6 = 0110
+7 = 0111
+8 = 1000
+9 = 1001
+A = 1010
+B = 1011
+C = 1100
+D = 1101
+E = 1110
+F = 1111
+</code></pre>
+<p>The BITS transmission contains a single <em>packet</em> at its outermost layer which itself contains many other packets. The hexadecimal representation of this packet might encode a few extra <code>0</code> bits at the end; these are not part of the transmission and should be ignored.</p>
+<p>Every packet begins with a standard header: the first three bits encode the packet <em>version</em>, and the next three bits encode the packet <em>type ID</em>. These two values are numbers; all numbers encoded in any packet are represented as binary with the most significant bit first. For example, a version encoded as the binary sequence <code>100</code> represents the number <code>4</code>.</p>
+<p>Packets with type ID <code>4</code> represent a <em>literal value</em>. Literal value packets encode a single binary number. To do this, the binary number is padded with leading zeroes until its length is a multiple of four bits, and then it is broken into groups of four bits. Each group is prefixed by a <code>1</code> bit except the last group, which is prefixed by a <code>0</code> bit. These groups of five bits immediately follow the packet header. For example, the hexadecimal string <code>D2FE28</code> becomes:</p>
+<pre><code>110100101111111000101000
+VVVTTTAAAAABBBBBCCCCC
+</code></pre>
+<p>Below each bit is a label indicating its purpose:</p>
+<ul>
+<li>The three bits labeled <code>V</code> (<code>110</code>) are the packet version, <code>6</code>.</li>
+<li>The three bits labeled <code>T</code> (<code>100</code>) are the packet type ID, <code>4</code>, which means the packet is a literal value.</li>
+<li>The five bits labeled <code>A</code> (<code>10111</code>) start with a <code>1</code> (not the last group, keep reading) and contain the first four bits of the number, <code>0111</code>.</li>
+<li>The five bits labeled <code>B</code> (<code>11110</code>) start with a <code>1</code> (not the last group, keep reading) and contain four more bits of the number, <code>1110</code>.</li>
+<li>The five bits labeled <code>C</code> (<code>00101</code>) start with a <code>0</code> (last group, end of packet) and contain the last four bits of the number, <code>0101</code>.</li>
+<li>The three unlabeled <code>0</code> bits at the end are extra due to the hexadecimal representation and should be ignored.</li>
+</ul>
+<p>So, this packet represents a literal value with binary representation <code>011111100101</code>, which is <code>2021</code> in decimal.</p>
+<p>Every other type of packet (any packet with a type ID other than <code>4</code>) represent an <em>operator</em> that performs some calculation on one or more sub-packets contained within. Right now, the specific operations aren't important; focus on parsing the hierarchy of sub-packets.</p>
+<p>An operator packet contains one or more packets. To indicate which subsequent binary data represents its sub-packets, an operator packet can use one of two modes indicated by the bit immediately after the packet header; this is called the <em>length type ID</em>:</p>
+<ul>
+<li>If the length type ID is <code>0</code>, then the next <em>15</em> bits are a number that represents the <em>total length in bits</em> of the sub-packets contained by this packet.</li>
+<li>If the length type ID is <code>1</code>, then the next <em>11</em> bits are a number that represents the <em>number of sub-packets immediately contained</em> by this packet.</li>
+</ul>
+<p>Finally, after the length type ID bit and the 15-bit or 11-bit field, the sub-packets appear.</p>
+<p>For example, here is an operator packet (hexadecimal string <code>38006F45291200</code>) with length type ID <code>0</code> that contains two sub-packets:</p>
+<pre><code>00111000000000000110111101000101001010010001001000000000
+VVVTTTILLLLLLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBBBBBB
+</code></pre>
+<ul>
+<li>The three bits labeled <code>V</code> (<code>001</code>) are the packet version, <code>1</code>.</li>
+<li>The three bits labeled <code>T</code> (<code>110</code>) are the packet type ID, <code>6</code>, which means the packet is an operator.</li>
+<li>The bit labeled <code>I</code> (<code>0</code>) is the length type ID, which indicates that the length is a 15-bit number representing the number of bits in the sub-packets.</li>
+<li>The 15 bits labeled <code>L</code> (<code>000000000011011</code>) contain the length of the sub-packets in bits, <code>27</code>.</li>
+<li>The 11 bits labeled <code>A</code> contain the first sub-packet, a literal value representing the number <code>10</code>.</li>
+<li>The 16 bits labeled <code>B</code> contain the second sub-packet, a literal value representing the number <code>20</code>.</li>
+</ul>
+<p>After reading 11 and 16 bits of sub-packet data, the total length indicated in <code>L</code> (27) is reached, and so parsing of this packet stops.</p>
+<p>As another example, here is an operator packet (hexadecimal string <code>EE00D40C823060</code>) with length type ID <code>1</code> that contains three sub-packets:</p>
+<pre><code>11101110000000001101010000001100100000100011000001100000
+VVVTTTILLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBCCCCCCCCCCC
+</code></pre>
+<ul>
+<li>The three bits labeled <code>V</code> (<code>111</code>) are the packet version, <code>7</code>.</li>
+<li>The three bits labeled <code>T</code> (<code>011</code>) are the packet type ID, <code>3</code>, which means the packet is an operator.</li>
+<li>The bit labeled <code>I</code> (<code>1</code>) is the length type ID, which indicates that the length is a 11-bit number representing the number of sub-packets.</li>
+<li>The 11 bits labeled <code>L</code> (<code>00000000011</code>) contain the number of sub-packets, <code>3</code>.</li>
+<li>The 11 bits labeled <code>A</code> contain the first sub-packet, a literal value representing the number <code>1</code>.</li>
+<li>The 11 bits labeled <code>B</code> contain the second sub-packet, a literal value representing the number <code>2</code>.</li>
+<li>The 11 bits labeled <code>C</code> contain the third sub-packet, a literal value representing the number <code>3</code>.</li>
+</ul>
+<p>After reading 3 complete sub-packets, the number of sub-packets indicated in <code>L</code> (3) is reached, and so parsing of this packet stops.</p>
+<p>For now, parse the hierarchy of the packets throughout the transmission and <em>add up all of the version numbers</em>.</p>
+<p>Here are a few more examples of hexadecimal-encoded transmissions:</p>
+<ul>
+<li><code>8A004A801A8002F478</code> represents an operator packet (version 4) which contains an operator packet (version 1) which contains an operator packet (version 5) which contains a literal value (version 6); this packet has a version sum of <code><em>16</em></code>.</li>
+<li><code>620080001611562C8802118E34</code> represents an operator packet (version 3) which contains two sub-packets; each sub-packet is an operator packet that contains two literal values. This packet has a version sum of <code><em>12</em></code>.</li>
+<li><code>C0015000016115A2E0802F182340</code> has the same structure as the previous example, but the outermost packet uses a different length type ID. This packet has a version sum of <code><em>23</em></code>.</li>
+<li><code>A0016C880162017C3686B18A3D4780</code> is an operator packet that contains an operator packet that contains an operator packet that contains five literal values; it has a version sum of <code><em>31</em></code>.</li>
+</ul>
+<p>Decode the structure of your hexadecimal-encoded BITS transmission; <em>what do you get if you add up the version numbers in all packets?</em></p>
+</article>
+<p>Your puzzle answer was <code>852</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>Now that you have the structure of your transmission decoded, you can calculate the value of the expression it represents.</p>
+<p>Literal values (type ID <code>4</code>) represent a single number as described above. The remaining type IDs are more interesting:</p>
+<ul>
+<li>Packets with type ID <code>0</code> are <em>sum</em> packets - their value is the sum of the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.</li>
+<li>Packets with type ID <code>1</code> are <em>product</em> packets - their value is the result of multiplying together the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.</li>
+<li>Packets with type ID <code>2</code> are <em>minimum</em> packets - their value is the minimum of the values of their sub-packets.</li>
+<li>Packets with type ID <code>3</code> are <em>maximum</em> packets - their value is the maximum of the values of their sub-packets.</li>
+<li>Packets with type ID <code>5</code> are <em>greater than</em> packets - their value is <em>1</em> if the value of the first sub-packet is greater than the value of the second sub-packet; otherwise, their value is <em>0</em>. These packets always have exactly two sub-packets.</li>
+<li>Packets with type ID <code>6</code> are <em>less than</em> packets - their value is <em>1</em> if the value of the first sub-packet is less than the value of the second sub-packet; otherwise, their value is <em>0</em>. These packets always have exactly two sub-packets.</li>
+<li>Packets with type ID <code>7</code> are <em>equal to</em> packets - their value is <em>1</em> if the value of the first sub-packet is equal to the value of the second sub-packet; otherwise, their value is <em>0</em>. These packets always have exactly two sub-packets.</li>
+</ul>
+<p>Using these rules, you can now work out the value of the outermost packet in your BITS transmission.</p>
+<p>For example:</p>
+<ul>
+<li><code>C200B40A82</code> finds the sum of <code>1</code> and <code>2</code>, resulting in the value <code><em>3</em></code>.</li>
+<li><code>04005AC33890</code> finds the product of <code>6</code> and <code>9</code>, resulting in the value <code><em>54</em></code>.</li>
+<li><code>880086C3E88112</code> finds the minimum of <code>7</code>, <code>8</code>, and <code>9</code>, resulting in the value <code><em>7</em></code>.</li>
+<li><code>CE00C43D881120</code> finds the maximum of <code>7</code>, <code>8</code>, and <code>9</code>, resulting in the value <code><em>9</em></code>.</li>
+<li><code>D8005AC2A8F0</code> produces <code>1</code>, because <code>5</code> is less than <code>15</code>.</li>
+<li><code>F600BC2D8F</code> produces <code>0</code>, because <code>5</code> is not greater than <code>15</code>.</li>
+<li><code>9C005AC2F8F0</code> produces <code>0</code>, because <code>5</code> is not equal to <code>15</code>.</li>
+<li><code>9C0141080250320F1802104A08</code> produces <code>1</code>, because <code>1</code> + <code>3</code> = <code>2</code> * <code>2</code>.</li>
+</ul>
+<p><em>What do you get if you evaluate the expression represented by your hexadecimal-encoded BITS transmission?</em></p>
+</article>
+<p>Your puzzle answer was <code>19348959966392</code>.</p><p class="day-success">Both parts of this puzzle are complete! They provide two gold stars: **</p>
+<p>At this point, you should <a href="/2021">return to your Advent calendar</a> and try another puzzle.</p>
+<p>If you still want to see it, you can <a href="16/input" target="_blank">get your puzzle input</a>.</p>
+<p>You can also <span class="share">[Share<span class="share-content">on
+ <a href="https://twitter.com/intent/tweet?text=I%27ve+completed+%22Packet+Decoder%22+%2D+Day+16+%2D+Advent+of+Code+2021&url=https%3A%2F%2Fadventofcode%2Ecom%2F2021%2Fday%2F16&related=ericwastl&hashtags=AdventOfCode" target="_blank">Twitter</a>
+ <a href="javascript:void(0);" onclick="var mastodon_instance=prompt('Mastodon Instance / Server Name?'); if(typeof mastodon_instance==='string' && mastodon_instance.length){this.href='https://'+mastodon_instance+'/share?text=I%27ve+completed+%22Packet+Decoder%22+%2D+Day+16+%2D+Advent+of+Code+2021+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2021%2Fday%2F16'}else{return false;}" target="_blank">Mastodon</a
+></span>]</span> this puzzle.</p>
+</main>
+
+<!-- ga -->
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-69522494-1', 'auto');
+ga('set', 'anonymizeIp', true);
+ga('send', 'pageview');
+</script>
+<!-- /ga -->
+</body>
+</html>
\ No newline at end of file