Created
December 16, 2021 19:57
-
-
Save armstnp/eeaf7d13ef1e7bc0dcab798355663727 to your computer and use it in GitHub Desktop.
Wispy Clojure - Cwojure?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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