aboutsummaryrefslogtreecommitdiffstats
path: root/src/aoc_2022/day05.clj
blob: 9b07a16534446209b486301243b8f8638f097860 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(ns aoc-2022.day05)
(require '[aoc-2022.utils :refer :all])

(defn split-by-empty-line [rows]
  (split-by "" rows))

(defn revv [v] (vec (rseq v)))

(defn parse-stacks [stacks]
  (->> stacks
       transpose
       (keep-indexed #(if (zero? (mod (- %1 1) 4)) %2 nil))
       (map #(filter (partial not= \ ) %))
       (map #(drop-last %))
       (map vec)))

(defn parse-instrs [instrs]
  (->> instrs
       (map #(split-by \  %))
       (map (partial keep-indexed #(if (odd? %1) (apply str %2) nil)))
       (map (partial map to-long))
       (map vec)
       ))

(defn prepare [rows]
  (let [[stack-rows instr-rows] (split-by-empty-line rows)
        stacks (parse-stacks stack-rows)
        instrs (parse-instrs instr-rows)]
    (list (vec stacks) (vec instrs))))

(defn run-instr1 [[n from to] stacks]
  (if (zero? n)
    stacks
    (let [from-stack (stacks (dec from))
          to-stack (stacks (dec to))
          val (first from-stack)
          new-from-stack (vec (rest from-stack))
          new-to-stack (vec (cons val to-stack))
          new-stacks' (assoc stacks (dec from) new-from-stack)
          new-stacks (assoc new-stacks' (dec to) new-to-stack)]
      (run-instr1 [(dec n) from to] new-stacks))))

(defn run-instrs1 [[instr & is] stacks]
  (if (seq instr)
    (run-instrs1 (vec is) (run-instr1 instr stacks))
    stacks))

(defn task1 [rows]
  (let [[stacks instrs] (prepare rows)]
    (->> (run-instrs1 instrs stacks)
         (map first)
         (apply str))))

(defn run-instr2 [[n from to] stacks]
  (let [from-stack (stacks (dec from))
        to-stack (stacks (dec to))
        vals (vec (take n from-stack))
        new-from-stack (vec (drop n from-stack))
        new-to-stack (vec (concat vals to-stack))
        new-stacks' (assoc stacks (dec from) new-from-stack)]
    (assoc new-stacks' (dec to) new-to-stack)))

(defn run-instrs2 [[instr & is] stacks]
  (if (seq instr)
    (run-instrs2 (vec is) (run-instr2 instr stacks))
    stacks))

(defn task2 [rows]
  (let [[stacks instrs] (prepare rows)]
    (->> (run-instrs2 instrs stacks)
         (map first)
         (apply str))))

(run-aoc "day05" task1 task2)