aboutsummaryrefslogtreecommitdiffstats
path: root/year2021/day16/part1.clj
diff options
context:
space:
mode:
Diffstat (limited to 'year2021/day16/part1.clj')
-rw-r--r--year2021/day16/part1.clj67
1 files changed, 67 insertions, 0 deletions
diff --git a/year2021/day16/part1.clj b/year2021/day16/part1.clj
new file mode 100644
index 0000000..2358e59
--- /dev/null
+++ b/year2021/day16/part1.clj
@@ -0,0 +1,67 @@
+(require '[clojure.string :as str])
+(require '[clojure.set :as set])
+
+(def hex-lookup
+ {\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"})
+
+(defn binary-to-num [binstr]
+ (reduce
+ #(cond-> %1 true (* 2) (= \1 %2) inc)
+ 0
+ binstr))
+
+(defn take-packet-version [packet]
+ (-> (split-at 3 packet)
+ (update 0 binary-to-num)))
+
+(defn take-literal-value [packet]
+ (let [[tid data] (split-at 3 packet)]
+ (when (= '(\1 \0 \0) tid)
+ (let [sd (into [] data)
+ spl (split-with #(= \1 (first %)) (partition 5 sd))
+ nums (map rest (concat (first spl) (take 1 (second spl))))]
+ [(binary-to-num (reduce concat nums))
+ (drop (* 5 (inc (count (first spl)))) sd)]
+ ))))
+
+(defn take-operator [packet]
+ (let [id (first packet) ps (str/join (rest packet))]
+ (if (= \0 id)
+ (let [bits (binary-to-num (subs ps 0 15))]
+ [(subs ps 15) bits :bits])
+ (let [pkts (binary-to-num (subs ps 0 11))]
+ [(subs ps 11) pkts :pkts]))))
+
+(defn process-packet [[input vcnt]]
+ (let [[version data] (take-packet-version input)]
+ (if (every? #(= \0 %) data)
+ ['() vcnt]
+ (do
+ (if-let [value (take-literal-value data)]
+ [(second value) (+ vcnt version)]
+ (do
+ (let [info (take-operator (drop 3 data))]
+ (if (= :bits (get info 2))
+ (loop [inpt [(subs (first info) 0 (get info 1)) (+ vcnt version)]]
+ (if (empty? (first inpt))
+ [(subs (first info) (get info 1)) (second inpt)]
+ (recur (process-packet inpt))))
+ (loop [n (get info 1) inpt [(get info 0) (+ vcnt version)]]
+ (if (pos? n)
+ (recur (dec n) (process-packet inpt))
+ inpt))))))))))
+
+(loop [packet (->> (slurp "./in")
+ (map hex-lookup)
+ (take-while some?)
+ (reduce concat)
+ (str/join)
+ (#(vector % 0))
+ (process-packet))]
+ (if (not (empty? (first packet)))
+ (recur (process-packet packet))
+ (println (second packet))))
+