Last active
December 7, 2023 19:53
-
-
Save borkdude/2a8c4e9e3baf00ea3c5f86d4f817166d to your computer and use it in GitHub Desktop.
AOC 2023 day 3 in squint + TC39 Tuples
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
;; Helper functions: | |
;; (fetch-input year day) - get AOC input | |
;; (append str) - append str to DOM | |
;; (spy x) - log x to console and return x | |
;; original solution: | |
;; https://github.com/russmatney/advent-of-code/blob/master/src/_2023/_03/core.clj | |
(require '["https://unpkg.com/@bloomberg/record-tuple-polyfill" :as tc39]) | |
(def input (->> (js-await (fetch-input 2023 3)) | |
str/split-lines)) | |
(def t js/Tuple) | |
(defn digit? [x] | |
(#{\1 \2 \3 \4 \5 \6 \7 \8 \9 \0} x)) | |
(defn ->grid | |
([raw] (->grid nil raw)) | |
([pred raw] | |
(->> raw | |
(map-indexed | |
(fn [y row] | |
(->> row (map-indexed | |
(fn [x char] | |
(if pred | |
(when (pred char) | |
[(t x y) char]) | |
[(t x y) char]))) | |
(filter seq) | |
(into [])))) | |
(filter seq) | |
(into []) | |
(apply concat) | |
(into (new js/Map))))) | |
(defn part? [char] | |
(not (or (= \. char) (digit? char)))) | |
(defn ->part-locs [raw] | |
(->grid part? raw)) | |
(comment | |
(->part-locs input) | |
(->grid input) | |
(->> "45..*.4" (map (fn [char] (digit? char))))) | |
(defn neighbors [[x y]] | |
#{(t x (inc y)) | |
(t x (dec y)) | |
(t (inc x) y) | |
(t (dec x) y) | |
(t (inc x) (inc y)) | |
(t (dec x) (dec y)) | |
(t (dec x) (inc y)) | |
(t (inc x) (dec y))}) | |
(defn x-num-neighbors [grid [x y]] | |
(let [->x-nbrs | |
(fn [->x] | |
(loop [new-coord (t (->x x) y) | |
nbrs []] | |
(cond | |
(nil? (get grid new-coord)) nbrs | |
(digit? (get grid new-coord)) | |
(recur (t (-> (first new-coord) ->x) y) (concat nbrs [new-coord])) | |
:else nbrs))) | |
left-nbrs (->x-nbrs dec) | |
right-nbrs (->x-nbrs inc)] | |
(concat (reverse left-nbrs) [(t x y)] right-nbrs))) | |
(comment | |
(x-num-neighbors (->grid input) (t 3 2)) | |
(x-num-neighbors (->grid input) [2 2]) | |
(x-num-neighbors (->grid input) [0 0]) | |
) | |
(defn coord->number [grid coord] | |
(let [num-coords (x-num-neighbors grid coord)] | |
[(first num-coords) | |
(->> num-coords | |
(map grid) | |
(apply str) | |
(parse-long))])) | |
(comment | |
(coord->number (->grid input) [2 2]) | |
(coord->number (->grid input) [0 0]) | |
) | |
(defn part-numbers | |
([raw] (part-numbers nil raw)) | |
([opts raw] | |
(let [grid (->grid raw) | |
part-locs (->part-locs raw)] | |
;; symbols->neighbor-digits | |
(cond->> part-locs | |
true | |
(map (fn [[coord sym]] | |
[sym | |
(let [nbrs (neighbors coord)] | |
(->> nbrs | |
(filter (fn [nbr] | |
(let [char (get grid nbr)] | |
(digit? char)))) | |
(map (fn [nbr] [nbr (get grid nbr)]))))])) | |
(:symbol opts) (filter (fn [[sym _nbrs]] | |
(#{(:symbol opts)} sym))) | |
true | |
(map (fn [[_sym nbrs]] | |
(->> nbrs | |
(map (fn [[coord _digit]] | |
(coord->number grid coord))) | |
(into {})))) | |
(:part-count opts) | |
(filter (fn [xs] | |
(= (:part-count opts) (count xs)))))))) | |
(comment | |
;; part 1 | |
(->> | |
(part-numbers input) | |
(map vals) | |
(apply concat) | |
(reduce +)) | |
;; part 2 | |
(->> | |
input | |
(part-numbers | |
{:symbol \* | |
:part-count 2}) | |
(map vals) | |
(map #(apply * %)) | |
(reduce +)) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment