blob: 4ade901a8485bdc2ecaea5d36653e628d9fcebbe (
plain)
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
56
57
|
(ns aoc-2022.utils)
(require '[clojure.string :as str])
; Debugging
(def spy #(do (println "DEBUG:" %) %))
; Number parsing
(def to-long #(Long/valueOf %))
(def to-float #(Float/valueOf %))
; Collections
(defn- split-by' [delim acc [x & xs]]
(condp = x
nil (list (reverse acc))
delim (cons (reverse acc) (split-by' delim '() xs))
; otherwise
(split-by' delim (cons x acc) xs)))
(def split-by #(split-by' %1 '() %2))
; Advent of Code specific
(defn read-aoc [day]
(let [slurp-f #(str/split-lines (slurp (format % day)))]
{:sample (slurp-f "resources/%s_sample.txt")
:actual (slurp-f "resources/%s_actual.txt")}))
(defn run-aoc
"Reads input files for `day` and invokes given `task1` and `task2` functions with the contents.
`task1` and `task2` should take a list of strings as their first argument."
[day task1 task2]
(let [{:keys [sample actual]} (read-aoc day)]
(do
(println "task1 @ sample:" (task1 sample))
(println "task1 @ actual:" (task1 actual))
(println "task2 @ sample:" (task2 sample))
(println "task2 @ actual:" (task2 actual)))))
; Functions
(defn chain "forward compose: comp fns in reverse order" [& fns]
(apply comp (reverse fns)))
; Logic
(defmacro nand
"Logical NAND. `(nand a b c)` is equivalent to `(not (and a b c))`."
[& args]
(list 'not (cons 'and args)))
(defmacro nor
"Logical NOR. `(nor a b c)` is equivalent to `(not (or a b c))`."
[& args]
(list 'not (cons 'or args)))
|