Created
December 3, 2023 13:58
-
-
Save ghadishayban/c09b298235f73cb56e223f46c53873e5 to your computer and use it in GitHub Desktop.
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 day3 | |
(:require [util])) | |
(defn adjacent-range | |
"returns [(dec lo), (inc hi)], lo clamped by 0, hi clamped by arg" | |
[lo hi hi-clamp] | |
[(max (dec lo) 0) | |
(min (inc hi) hi-clamp)]) | |
(defn scan-adjacent | |
"Calls (f line adjacent-lines) for every line, concatenating results. | |
Every line has 3 adjacent lines, except for the first and last lines" | |
[f lines] | |
(->> (range (count lines)) | |
(mapcat (fn [n] | |
(let [[lo hi] (adjacent-range n (inc n) (count lines)) | |
adjacent (map lines (range lo hi))] | |
(f (lines n) adjacent)))))) | |
(defn touching? | |
"given bounds (hi exclusive) returns predicate of match rets (from util/match)" | |
[lo hi] | |
(fn [{:keys [start end]}] | |
(and (> end lo) (< start hi)))) | |
(defn extract-part-nums | |
"returns coll of integer parts" | |
[line adjacent] | |
(let [len (count line) | |
symbols (mapcat #(util/matches #"[^.0-9]" %) adjacent)] | |
(->> (util/matches #"\d+" line) | |
(keep (fn [{:keys [start end match]}] | |
(let [[lo hi] (adjacent-range start end len)] | |
(when (some (touching? lo hi) symbols) | |
(parse-long match)))))))) | |
(defn extract-gears | |
"returns coll of gear maps with key :ratio" | |
[line adjacent] | |
(let [len (count line) | |
numbers (mapcat #(util/matches #"\d+" %) adjacent)] | |
(->> (util/matches #"\*" line) ;; collect candidate gears | |
(map (fn [{:keys [start end]}] | |
(let [[lo hi] (adjacent-range start end len)] | |
;; and the numbers that they touch | |
(filter (touching? lo hi) numbers)))) | |
(filter #(= 2 (count %))) | |
(map (fn [nums] | |
{:ratio (apply * (map (comp parse-long :match) nums))}))))) | |
(comment | |
;; part1 | |
(apply + (scan-adjacent extract-part-nums (util/lines "day3.input"))) | |
;; part2 | |
(apply + (map :ratio (scan-adjacent extract-gears (util/lines "day3.input"))))) |
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 util | |
(:require [clojure.java.io :as jio])) | |
(defn lines | |
[fname] | |
(with-open [r (jio/reader fname)] | |
(vec (line-seq r)))) | |
(defn matches | |
"for every match in s, returns :start/:end indexes, end exclusive, and :match, the matching (sub)string" | |
[regex s] | |
(let [m (re-matcher regex s)] | |
(loop [acc []] | |
(if (.find m) | |
(recur (conj acc {:start (.start m) | |
:end (.end m) | |
:match (.group m)})) | |
acc)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment