day 6
This commit is contained in:
parent
016ad690cd
commit
ee770ebd94
113
src/day6.clj
Normal file
113
src/day6.clj
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
(ns day6
|
||||||
|
(:require [clojure.string :as string]
|
||||||
|
[helpers :refer [get-input]]))
|
||||||
|
|
||||||
|
(def example
|
||||||
|
"....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#..^.....
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...")
|
||||||
|
|
||||||
|
(def input
|
||||||
|
(->>
|
||||||
|
;example
|
||||||
|
(get-input 6)
|
||||||
|
string/split-lines
|
||||||
|
(mapv vec)))
|
||||||
|
|
||||||
|
(def width (count (first input)))
|
||||||
|
(def height (count input))
|
||||||
|
|
||||||
|
(def initial-position
|
||||||
|
(first
|
||||||
|
(for [l (range height)
|
||||||
|
c (range width)
|
||||||
|
:when (= \^ (get-in input [l c]))]
|
||||||
|
[l c])))
|
||||||
|
|
||||||
|
(defn move [[l c] direction]
|
||||||
|
(case direction
|
||||||
|
:up [(dec l) c]
|
||||||
|
:right [l (inc c)]
|
||||||
|
:down [(inc l) c]
|
||||||
|
:left [l (dec c)]))
|
||||||
|
|
||||||
|
(defn turn-right [direction]
|
||||||
|
(case direction
|
||||||
|
:up :right
|
||||||
|
:right :down
|
||||||
|
:down :left
|
||||||
|
:left :up))
|
||||||
|
|
||||||
|
(defn left? [[l c]]
|
||||||
|
(or (neg? l) (neg? c) (= width c) (= height l)))
|
||||||
|
|
||||||
|
(defn obstructed? [pos map]
|
||||||
|
(= \# (get-in map pos)))
|
||||||
|
|
||||||
|
(def area-map
|
||||||
|
(loop [lab (assoc-in input initial-position \X)
|
||||||
|
position initial-position
|
||||||
|
direction :up]
|
||||||
|
(if (left? position)
|
||||||
|
lab
|
||||||
|
(if (obstructed? (move position direction) input)
|
||||||
|
(recur (assoc-in lab position \X) position (turn-right direction))
|
||||||
|
(recur (assoc-in lab position \X) (move position direction) direction)))))
|
||||||
|
|
||||||
|
(time
|
||||||
|
(println "Guard will visit"
|
||||||
|
(->>
|
||||||
|
(apply concat area-map)
|
||||||
|
(filter (partial = \X))
|
||||||
|
count)
|
||||||
|
"positions"))
|
||||||
|
|
||||||
|
(def possible-obstructions
|
||||||
|
(for [l (range height)
|
||||||
|
c (range width)
|
||||||
|
:when (= \. (get-in input [l c]))]
|
||||||
|
[l c]))
|
||||||
|
|
||||||
|
(defn has-loop? [xs]
|
||||||
|
(if (< (count xs) 3) false
|
||||||
|
(let [x (peek xs)
|
||||||
|
xs (reverse (pop xs))
|
||||||
|
[a b] (split-with (partial not= x) xs)]
|
||||||
|
(if (empty? b)
|
||||||
|
false
|
||||||
|
(loop [a a b (rest b)]
|
||||||
|
(if (empty? a)
|
||||||
|
true
|
||||||
|
(if (not= (first a) (first b))
|
||||||
|
false
|
||||||
|
(recur (rest a) (rest b)))))))))
|
||||||
|
|
||||||
|
(defn stuck? [obstruction]
|
||||||
|
(let [map' (assoc-in input obstruction \#)]
|
||||||
|
(loop [position initial-position
|
||||||
|
direction :up
|
||||||
|
encountered-obstructions []]
|
||||||
|
(if (left? position)
|
||||||
|
false
|
||||||
|
(if (has-loop? encountered-obstructions)
|
||||||
|
true
|
||||||
|
(let [new-pos (move position direction)]
|
||||||
|
(if (obstructed? new-pos map')
|
||||||
|
(recur position
|
||||||
|
(turn-right direction)
|
||||||
|
(conj encountered-obstructions new-pos))
|
||||||
|
(recur new-pos direction encountered-obstructions))))))))
|
||||||
|
|
||||||
|
(time
|
||||||
|
(println "Possible obstructions to make guard loop:"
|
||||||
|
(->>
|
||||||
|
(map stuck? possible-obstructions)
|
||||||
|
(filter true?)
|
||||||
|
count)))
|
||||||
Loading…
x
Reference in New Issue
Block a user