-
-
Save galuque/2fec8a886e1cb24f17662fda438d7e83 to your computer and use it in GitHub Desktop.
This file contains 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 io.github.galuque.aoc-2021.day-3 | |
(:require [clojure.java.io :as io] | |
[clojure.string :as str])) | |
(def input | |
(-> "day_3/input.txt" | |
io/resource | |
slurp)) | |
(def sample-input "00100 | |
11110 | |
10110 | |
10111 | |
10101 | |
01111 | |
00111 | |
11100 | |
10000 | |
11001 | |
00010 | |
01010 | |
") | |
(defn parse-input [input] | |
(->> input | |
str/split-lines | |
(mapv #(str/split % #"")) | |
(mapv #(mapv parse-long %)))) | |
(defn transpose [mx] | |
(apply mapv vector mx)) | |
(defn parse-binary [s] | |
(Long/valueOf s 2)) | |
(defn bit-frequecies [mx] | |
(->> mx | |
transpose | |
(mapv frequencies))) | |
(def coeff {:gamma [] | |
:epsilon []}) | |
(defn get-most-common-bit [m] | |
(let [zeroes (m 0) | |
ones (m 1)] | |
(if (<= zeroes ones) 1 0))) | |
(defn get-least-common-bit [m] | |
(let [zeroes (m 0) | |
ones (m 1)] | |
(if (<= zeroes ones) 0 1))) | |
(defn report [coeff m] | |
(let [most-common-bit (get-most-common-bit m) | |
least-common-bit ({1 0 0 1} most-common-bit)] | |
(-> coeff | |
(update :gamma conj most-common-bit) | |
(update :epsilon conj least-common-bit)))) | |
(defn part-1 [input] | |
(let [freqs (bit-frequecies input) | |
rates (reduce report coeff freqs) | |
gamma (-> (:gamma rates) str/join parse-binary) | |
epsilon (-> (:epsilon rates) str/join parse-binary)] | |
(* gamma epsilon))) | |
(comment | |
(part-1 (parse-input sample-input)) | |
;; => 198 | |
(part-1 (parse-input input)) | |
;; => 2640986 | |
) | |
(defn find-rating [criteria-fn input] | |
(loop [numbers input | |
idx 0] | |
(let [bit (-> numbers bit-frequecies (nth idx) criteria-fn) | |
filtered (into [] | |
(filter (fn [v] (= bit (nth v idx)))) | |
numbers)] | |
(if (= 1 (count filtered)) | |
(first filtered) | |
(recur filtered (inc idx)))))) | |
(defn part-2 [input] | |
(let [o2-vec (find-rating get-most-common-bit input) | |
co2-vec (find-rating get-least-common-bit input) | |
o2 (-> o2-vec str/join parse-binary) | |
co2 (-> co2-vec str/join parse-binary)] | |
(* o2 co2))) | |
(comment | |
(part-2 (parse-input sample-input)) | |
;; => 230 | |
(part-2 (parse-input input)) | |
;; => 6822109 | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment