Advent of Code 2018 - Day 3
(ns aoc.aoc3 | |
(:require [clojure.string :as s] | |
[clojure.set :as set])) | |
(defrecord Claim [claim-number squares]) | |
(defn convert-to-grid | |
"Converts a claim into a sequence of 'taken' squares." | |
[claim grid-width] | |
;; Named groups would be great here, but Clojure doesn't support this natively. | |
(let [matcher #"#(?<claim>\d+)\s@\s(?<x>\d+),(?<y>\d+):\s(?<width>\d+)x(?<height>\d+)$" | |
matches (re-find matcher claim) | |
[_ claim horiz vert width height] matches | |
x (Integer. horiz) | |
y (Integer. vert) | |
w (Integer. width) | |
h (Integer. height) | |
rows (take h (iterate inc y))] | |
(->> (map #(range (+ x (* grid-width %)) (+ (+ x w) (* grid-width %))) rows) | |
(flatten) | |
(set) | |
(Claim. (Integer. claim) )))) | |
(defn get-overlap | |
"returns the amount of overlap based on calculated inputs. | |
Answer provided in square units matching the units entered | |
(for the case of the problem, square inches)." | |
[claims] | |
;; Perform intersection to find any matches, then union to combine; repeat through the list. | |
(loop [mapped-area (map #(convert-to-grid % 1000) claims) | |
shared-fabric #{} | |
intersections #{}] | |
(if (empty? mapped-area) | |
intersections | |
(let [intersect (set/intersection shared-fabric (:squares (first mapped-area))) | |
union (set/union shared-fabric (:squares (first mapped-area)))] | |
(recur (rest mapped-area) union (set/union intersections intersect)))))) | |
(defn overlapping-claim [c1 c2] | |
(cond | |
(= (:claim-number c1) (:claim-number c2)) nil | |
(not-empty (set/intersection (:squares c1) (:squares c2))) c2)) | |
(defn find-no-overlap | |
"given a set of input claims, find the claim that has no overlap | |
with any other claims." | |
[claims] | |
(let [grid-claims (map #(convert-to-grid % 1000) claims)] | |
(loop [idx 0 ignores #{}] | |
(if-not (contains? (:claim-id (nth grid-claims idx)) ignores) | |
(if-let [overlap (some #(overlapping-claim (nth grid-claims idx) %) grid-claims)] | |
(recur (inc idx) (conj ignores (:claim-number overlap))) | |
(:claim-number (nth grid-claims idx))) | |
(recur (inc idx) ignores))))) |
(ns aoc.aoc3-test | |
(:require [aoc.aoc3 :as sut] | |
[clojure.test :refer :all])) | |
(deftest convert-to-grid-test | |
(testing "convert-to-grid" | |
(testing "a simple example" | |
(is (= (set '(2 3 4 7 8 9 12 13 14)) (:squares (sut/convert-to-grid "#1 @ 2,0: 3x3" 5))))))) | |
(deftest part1 | |
(testing "provided example" | |
(let [input-values ["#1 @ 1,3: 4x4" | |
"#2 @ 3,1: 4x4" | |
"#3 @ 5,5: 2x2"]] | |
(is (= 4 (count (sut/get-overlap input-values))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment