You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.3 KiB
Clojure
73 lines
2.3 KiB
Clojure
(require '[clojure.core.reducers :as r])
|
|
(require 'clojure.string)
|
|
|
|
(defn build-scanner-reports [input-lines]
|
|
(loop [scanners [] rem-input input-lines]
|
|
(if (empty? rem-input)
|
|
scanners
|
|
(let [[this nxt] (split-with (comp not empty?) rem-input)]
|
|
(recur
|
|
(->> (rest this)
|
|
(map #(read-string (clojure.string/join ["[" % "]"])))
|
|
(conj scanners))
|
|
(rest nxt))))))
|
|
|
|
(defn all-orientations [[x y z]]
|
|
(map (fn [[i j k]] [(* x i) (* y j) (* z k)])
|
|
'([1 1 1] [-1 1 1] [1 -1 1] [-1 -1 1] [1 1 -1] [-1 1 -1] [1 -1 -1] [-1 -1 -1])))
|
|
|
|
(defn group-orientations [lst]
|
|
(for [i (range 0 8)] (map #(nth % i) lst)))
|
|
|
|
(defn scanner-orientations [scanner]
|
|
(group-orientations (map all-orientations scanner)))
|
|
|
|
(defn add-coordinate [[a b c] [d e f]] [(+ a d) (+ b e) (+ c f)])
|
|
|
|
(defn add-coordinate-lists [l1 l2]
|
|
(for [i (range 0 (count l1))]
|
|
(for [j (range 0 (count l2))]
|
|
(add-coordinate (nth l1 i) (nth l2 j)))))
|
|
|
|
(defn compare-scanners [s1 s2]
|
|
(let [o1 [s1];(scanner-orientations s1)
|
|
o2 (scanner-orientations s2)]
|
|
(for [o o1 p o2]
|
|
(add-coordinate-lists o p))))
|
|
|
|
(defn check-beacon-coord [scanner coord index]
|
|
(not (empty? (filter #(= coord %) (map #(nth % index) scanner)))))
|
|
|
|
(defn beacon-coord-match? [req coord compared-scanners]
|
|
(let [cnt (count (first (first compared-scanners)))]
|
|
(< (dec req)
|
|
(reduce
|
|
(fn [tot n]
|
|
(cond-> tot
|
|
(and (< tot req)
|
|
(reduce
|
|
#(or %1 %2)
|
|
(map #(check-beacon-coord % coord n) compared-scanners)))
|
|
inc))
|
|
0
|
|
(range 0 cnt)))))
|
|
|
|
(->> (slurp "./in")
|
|
(clojure.string/split-lines)
|
|
(build-scanner-reports)
|
|
((fn [scanners]
|
|
(for [s1i (range 0 (count scanners))
|
|
s2 (drop (inc s1i) scanners)
|
|
:let [res (compare-scanners (nth scanners s1i) s2)]]
|
|
(let [cnt (count (first (first res)))]
|
|
(into '()
|
|
(r/fold
|
|
r/cat
|
|
(fn [final c]
|
|
(cond-> final
|
|
(beacon-coord-match? 4 c res)
|
|
(r/append! c)))
|
|
(into [] (distinct (nth (iterate (partial reduce concat) res) 2)))))))))
|
|
(println))
|
|
|