Skip to content

Instantly share code, notes, and snippets.

@armstnp
Created December 16, 2021 19:57
Show Gist options
  • Save armstnp/eeaf7d13ef1e7bc0dcab798355663727 to your computer and use it in GitHub Desktop.
Save armstnp/eeaf7d13ef1e7bc0dcab798355663727 to your computer and use it in GitHub Desktop.
Wispy Clojure - Cwojure?
ns advent-of-code-2021.day16
:require [advent-of-code-2021.core :as core]
. [clojure.string :as str]
def bitmap
. {\0 [0 0 0 0]
\1 [0 0 0 1]
\2 [0 0 1 0]
\3 [0 0 1 1]
\4 [0 1 0 0]
\5 [0 1 0 1]
\6 [0 1 1 0]
\7 [0 1 1 1]
\8 [1 0 0 0]
\9 [1 0 0 1]
\A [1 0 1 0]
\B [1 0 1 1]
\C [1 1 0 0]
\D [1 1 0 1]
\E [1 1 1 0]
\F [1 1 1 1]}
def input
->> "day16.txt"
. core/read-input
. mapcat bitmap
;; Part 1 Solution
defn bits->int [bits]
Long/parseLong (apply str bits) 2
declare parse-packet
defn parse-literal [bits]
loop [bits bits
literal []]
let
:[
[[flag & sub-bits] bits'] : split-at 5 bits
literal' : concat literal sub-bits
if : zero? flag
[(bits->int literal') bits']
recur bits' literal'
defn parse-* [bits]
loop [bits bits
accum []]
if : empty? bits
accum
let
:[
[parsed bits'] : parse-packet bits
accum' : conj accum parsed
recur bits' accum'
defn parse-n [n bits]
loop [remaining n
bits bits
accum []]
if : zero? remaining
[accum bits]
let [[parsed bits'] (parse-packet bits)]
recur
dec remaining
bits'
conj accum parsed
defn parse-operator [bits]
let [[length-type-id & bits'] bits]
if : zero? length-type-id
let
:[
[length-bits bits'] : split-at 15 bits'
bit-length : bits->int length-bits
[body-bits bits'] : split-at bit-length bits'
[(parse-* body-bits) bits']
let
:[
[length-bits bits'] : split-at 11 bits'
num-packets : bits->int length-bits
parse-n num-packets bits'
defn parse-packet [bits]
let
:[
[version bits'] : split-at 3 bits
version : bits->int version
[type-id bits'] : split-at 3 bits'
type-id : bits->int type-id
parse : if {- type-id = 4 -} parse-literal parse-operator
[body bits'] : parse bits'
:[
:{
:version version
:type-id type-id
:body body
bits'
defn sum-versions [{:keys [version body]}]
+ version
if : vector? body
reduce + : map sum-versions body
0
->> input
. parse-packet
. first
. sum-versions
;; Part 2 Solution
defn execute-packet [{:keys [type-id body]}]
if {- type-id = 4 -}
body
let [op (case type-id
0 +
1 *
2 min
3 max
5 #(if (> %1 %2) 1 0)
6 #(if (< %1 %2) 1 0)
7 #(if (= %1 %2) 1 0))]
apply op : map execute-packet body
->> input
. parse-packet
. first
. execute-packet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment