Skip to content

Instantly share code, notes, and snippets.

@ChrisBlom ChrisBlom/advent-of-code.clj Secret

Last active Jan 9, 2018
Embed
What would you like to do?
;;;; infi
(defn parse-log [log-strings]
(->> log-strings
(format "[%s]") ; surround with bracket so the whole input can be parsed as a edn vector
read-string))
(def infi-in (parse-log (slurp "https://infiaoc.azurewebsites.net/api/aoc/input/2017/T3ZMOSS7F9MM")))
;; Exploit the fact the the input defines start positions with [], and moves with (),
;; clojure parses [] as vectors, and () as lists
(def infi-ex (parse-log "[0,0][1,1](1,0)(0,-1)(0,1)(-1,0)(-1,0)(0,1)(0,-1)(1,0)"))
(defn perform-move
"takes a vector of positions and a vector of moves
returns next positions by adding the moves to the positions"
[positions moves]
{:pre [(= (count positions) (count moves))]}
(mapv (fn [position move] (mapv + position move)) positions moves))
(defn paths [log]
"takes a puzzle input, split the start positions (which are vectors)
from the moves (which are lists)
Returns the sequence of positions as they are updates with the moves"
(let [ [start-positions changes] (split-with vector? log)
moves (partition (count start-positions) changes)]
(reductions perform-move start-positions moves)))
(defn clash?
"takes a list of positions, returns true iff positions overlap"
[positions]
(not= (distinct positions) positions))
(defn count-clashes
"given a puzzle input, returns the number of times positions overlapped"
[log]
(count (filter clash? (paths log))))
(assert (= (count-clashes infi-ex) 2) "solution does not match for example")
;; solution for part 1
(doto (count-clashes infi-in) println)
;;;; Part 2
(def infi-in-2 (parse-log (slurp "https://infiaoc.azurewebsites.net/api/aoc/input/2017/T3ZMOSS7F9MM")))
(def part-2-paths (paths infi-in-2))
;; find the largest x,y positions
(def range-y (apply max (for [step part-2-paths
[x y] step]
y)))
(def range-x (apply max (for [step part-2-paths
[x y] step]
x)))
(defn print-grid
"takes a grid and prints it to stdout"
[grid]
(doseq [row grid]
(doseq [cell row]
(print cell))
(println)))
;; Define a grid that is large enough to fit all positions
(def grid (make-array String (inc range-y) (inc range-x)))
;; init grid with spaces
(doseq [y (range 0 (inc range-y))
x (range 0 (inc range-x))]
(aset grid y x " "))
;; set clash positions to a square
(doseq [positions part-2-paths
[x y] positions
:when (clash? positions)]
(aset grid y x ""))
;; solution for part 2
(print-grid grid)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.