-
-
Save galuque/b0a932f8b262c3b6b9f993383ae61ea5 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-5 | |
(:require [clojure.java.io :as io] | |
[clojure.string :as str] | |
[clojure.set :as set])) | |
(def input (-> "day_5/input.txt" | |
io/resource | |
slurp)) | |
(def sample-input "0,9 -> 5,9 | |
8,0 -> 0,8 | |
9,4 -> 3,4 | |
2,2 -> 2,1 | |
7,0 -> 7,4 | |
6,4 -> 2,0 | |
0,9 -> 2,9 | |
3,4 -> 1,4 | |
0,0 -> 8,8 | |
5,5 -> 8,2 | |
") | |
(defn parse-point [s] | |
(mapv parse-long (str/split s #","))) | |
(defn parse-line [line] | |
(mapv parse-point line)) | |
(defn parse-input [input] | |
(->> input | |
(re-seq #"\d+,\d+ -> \d+,\d+") | |
(mapv (comp | |
(partial parse-line) | |
(partial re-seq #"\d+,\d+"))))) | |
(defn horizontal-line? [line] | |
(let [[_ y1 _ y2] (flatten line)] | |
(= y1 y2))) | |
(defn vertical-line? [line] | |
(let [[x1 _ x2 _] (flatten line)] | |
(= x1 x2))) | |
(defn line->points* [a b common] | |
(partition 2 (interleave (repeat common) (range a (inc b))))) | |
(defn diag-range [a b] | |
(if (< a b) | |
(range a (inc b)) | |
(range a (dec b) -1 ))) | |
(defn line->points [line] | |
(let [[x1 y1 x2 y2] (flatten line)] | |
(cond | |
(vertical-line? line) | |
(if (< y1 y2) | |
(line->points* y1 y2 x1) | |
(line->points* y2 y1 x1)) | |
(horizontal-line? line) | |
(if (< x1 x2) | |
(map reverse (line->points* x1 x2 y1)) | |
(map reverse (line->points* x2 x1 y1))) | |
:else | |
(partition 2 | |
(interleave (diag-range x1 x2) | |
(diag-range y1 y2)))))) | |
(defn intersections [line1 line2] | |
(set/intersection (set (line->points line1)) | |
(set (line->points line2)))) | |
(defn solution [lines] | |
(let [inters (for [line1 lines | |
line2 lines | |
:when (not= line1 line2)] | |
(intersections line1 line2))] | |
(->> inters | |
(filter not-empty) | |
frequencies | |
(filter #(-> % val (>= 2))) | |
(map first) | |
(apply set/union) | |
count))) | |
(defn part-1 [input] | |
(let [lines (filterv (some-fn vertical-line? | |
horizontal-line?) | |
input)] | |
(solution lines))) | |
(comment | |
(part-1 (parse-input sample-input)) | |
;; => 5 | |
(part-1 (parse-input input)) | |
;; => 6710 | |
) | |
(def part-2 solution) | |
(comment | |
(part-2 (parse-input sample-input)) | |
;; => 12 | |
(part-2 (parse-input input)) | |
;; => 20121 | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment