-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12.clj
55 lines (48 loc) · 1.68 KB
/
day12.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
(ns clojure-solutions.day12
(:require [clojure.string :as str]
[clojure.set :as set])
(:use [clojure-solutions.util] :reload))
(defn- parse []
(->> (slurp "./input/day12.txt")
str/split-lines
(map #(str/split % #"-"))
(map (fn [[k v]] ; paths are bidirectional
(into {}
(filter-val #(not (elem :start %)))
{(keyword k) #{(keyword v)}
(keyword v) #{(keyword k)}})))
(apply merge-with set/union)))
(defn- small-cave? [kw]
(= (name kw) (str/lower-case (name kw))))
(defn- small-cave-twice [path]
(let [small-path (filter small-cave? path)]
(not= (count small-path) (count (set small-path)))))
(defn- solve [keep connections]
(letfn ((go [path kw]
(let [path* (conj path kw) ; new path
;; Places we can visit
downs (filter #(keep path* %) (connections kw))]
(if (= kw :end)
[path*]
(mapcat #(go path* %) downs)))))
(->> (connections :start)
(mapcat #(go [:start] %))
count)))
;; => 4754
(defn- part1 [xs]
(solve (fn [path x] (not (and (small-cave? x) (elem x path))))
xs))
;; => 143562
(defn- part2 [xs]
(solve (fn [path x]
;; If a small cave already appears twice, make sure it
;; doesn't happen again. Otherwise, just let everything
;; through.
(not (and (small-cave-twice path)
(small-cave? x)
(elem x path))))
xs))
(defn day12 []
(let [connections (parse)]
(println (part1 connections))
(println (part2 connections))))