Factor out A* implementation
[adventofcode2019.git] / src / adventofcode2019 / lib.clj
CommitLineData
cca08f5d 1(ns adventofcode2019.lib
7a710645
JK
2 [:require [clojure.string :as str]
3 [clojure.edn :as edn]
4 [clojure.java.io :as io]
fa02619e
JK
5 [clojure.java.shell :refer [sh]]
6 [clojure.data.priority-map :refer [priority-map-by]]])
cca08f5d
JK
7
8(defn get-list-from-file
9 ([file-name]
7a710645 10 (str/split-lines (str/trim (slurp file-name))))
cca08f5d 11 ([file-name split-regex]
7a710645 12 (str/split (str/trim (slurp file-name)) split-regex)))
cca08f5d 13
92053791
JK
14(defn parse-int [n]
15 (let [n-val (edn/read-string n)]
16 (if (number? n-val)
7a710645
JK
17 n-val
18 (throw (Exception. "Not a number!")))))
d0f13cd2 19
cca08f5d
JK
20(defmacro input-file []
21 (let [bottom-ns (last (str/split (str *ns*) #"\."))]
22 (str "resources/" bottom-ns)))
23
7a710645 24(defn manhattan-distance [[ax ay] [bx by]]
f1a195aa
JK
25 (+ (Math/abs (- ax bx))
26 (Math/abs (- ay by))))
27
fa02619e
JK
28(defn a-star
29 "succ :: state -> [state]
30 cost :: cost -> state -> cost
31 heur :: state -> cost
32 init :: state
33 des? :: state -> bool"
34 [succ cost heur init des?]
35 (let [update-openl (fn [ol sn pt cs]
36 (reduce (fn [o p]
37 (assoc o p [(cost cs p) (heur p)]))
38 ol (remove sn (succ pt))))
39 openl (priority-map-by (fn [[ag ah] [bg bh]]
40 (let [cmp (compare (+ ag ah) (+ bg bh))
41 cmp-g (compare ag bg)
42 cmp-h (compare ah bh)]
43 (if-not (zero? cmp)
44 cmp
45 (if-not (zero? cmp-g)
46 cmp-g
47 cmp-h)))))]
48 (loop [openl (assoc openl init [0 (heur init)])
49 seen #{init}]
50 (let [[point [dist _]] (peek openl)]
51 (cond
52 (empty? openl) [nil ##Inf]
53 (des? point) [point dist]
54 :else (let [openl (update-openl (pop openl) seen point dist)
55 seen (apply conj seen (keys openl))]
56 (recur openl seen)))))))
57
49dee54b 58(defn mmap [f m]
7a710645 59 (zipmap (keys m) (map f (vals m))))
49dee54b 60
7a710645 61(def part1
0503903a 62 #(println (str "Part 1: " %)))
7a710645 63(def part2
0503903a 64 #(println (str "Part 2: " %)))
d0f13cd2
JK
65
66;; FIXME: this is still broken but i give up for now
67; (defn --input-file [for-ns]
68; (let [bottom-ns (last (str/split for-ns #"\."))
69; input-url "https://adventofcode.com/2019/day/%d/input"
70; day-url (->> bottom-ns
71; (drop 3)
72; (str/join)
73; (parse-int)
74; (format input-url))
75; token (str/trim (slurp (io/resource "token")))
76; res-dir (-> (io/resource "token")
77; (.getPath)
78; (str/replace "token" bottom-ns))
79; cmd ["curl" "-s" "-b"
80; (format "\"session=%s\"" token)
81; day-url ">" res-dir]]
82; (if-let [input (io/resource bottom-ns)]
83; input
84; (do (apply sh cmd) nil))))
85
86; (defmacro input-file []
87; (--input-file (str *ns*)))