-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_05.clj
88 lines (83 loc) · 3.27 KB
/
day_05.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
(ns day_05
(:require
[utils :refer [open-resource parse-int]]
[clojure.string :refer [blank?]]))
(def input-file "day_05.txt")
(def data
(let [letter? #(or (Character/isLetter %) (Character/isDigit %))
to-map (fn [[f & r]] (hash-map (keyword f) r))
parse-command (fn [[amount from to]] (hash-map :amount (parse-int amount) :from (keyword from) :to (keyword to)))
clean-input (partition-by blank? (->> input-file open-resource))
stack (->> clean-input
first
reverse
(apply mapv vector)
(map #(filter letter? %))
(remove empty?)
(map #(map str %))
(map to-map)
(into {}))
commands (->> clean-input
last
(map #(re-seq #"\d+" %))
(map parse-command))]
(hash-map
:stack stack
:commands commands)))
(defn part-01 [input]
(let [process (fn [{stack :stack commands :commands}]
(loop [stack stack
commands commands]
(let [[command & rest] commands
new-stack (->> stack
(#(update-in
%
[(:to command)]
concat
(reverse
(take-last
(:amount command)
((:from command) %)))))
(#(update-in
%
[(:from command)]
(fn [x] (drop-last (:amount command) x)))))]
(if rest
(recur new-stack rest)
new-stack))))]
(->> input
process
(into (sorted-map))
vals
(map last)
(apply str))))
(defn part-02 [input]
(let [process (fn [{stack :stack commands :commands}]
(loop [stack stack
commands commands]
(let [[command & rest] commands
new-stack (->> stack
(#(update-in
%
[(:to command)]
concat
(take-last
(:amount command)
((:from command) %))))
(#(update-in
%
[(:from command)]
(fn [x] (drop-last (:amount command) x)))))]
(if rest
(recur new-stack rest)
new-stack))))]
(->> input
process
(into (sorted-map))
vals
(map last)
(apply str))))
(defn -main [& _]
(println "Day 05:")
(println "\t-> Part 1: " (part-01 data))
(println "\t-> Part 2: " (part-02 data)))