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