Skip to content

Instantly share code, notes, and snippets.

@galuque
Created December 5, 2021 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save galuque/b0a932f8b262c3b6b9f993383ae61ea5 to your computer and use it in GitHub Desktop.
Save galuque/b0a932f8b262c3b6b9f993383ae61ea5 to your computer and use it in GitHub Desktop.
(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