/
day11.clj
55 lines (45 loc) · 1.73 KB
/
day11.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 advent-of-code-2022.day11
(:require [common :refer [read-data-as-blocks split-line]]))
(def get-numbers (partial re-seq #"\d+"))
(def get-number (comp parse-long first get-numbers))
(defn maybe-long [v] (when-not (= v "old") (parse-long v)))
(defn parse
[[monkey items op divisor t f]]
{:id (get-number monkey)
:items (map parse-long (get-numbers items))
:divisor (get-number divisor)
:t (get-number t)
:f (get-number f)
:op (let [[a o b] (drop 3 (split-line op))
fun (resolve (symbol o))
[arga argb] (map maybe-long [a b])]
(fn [arg] (fun (if arga arga arg) (if argb argb arg))))})
(def data (mapv parse (read-data-as-blocks 2022 11)))
(defn inspect
[inspect-f monkeys id]
(let [{:keys [items divisor t f op]} (monkeys id)]
(-> (reduce (fn [m item]
(let [wl (inspect-f (op item))
target (if (zero? (mod wl divisor)) t f)]
(update-in m [target :items] conj wl))) monkeys items)
(update-in [id :items] empty)
(update-in [id :inspected] (fnil + 0) (count items)))))
(defn round
[inspect-f monkeys]
(reduce (partial inspect inspect-f) monkeys (map :id monkeys)))
(defn most-inspected
[data inspect-f cnt]
(->> (nth (iterate (partial round inspect-f) data) cnt)
(map :inspected)
(sort >)
(take 2)
(reduce *)))
(defn most-inspected1 [data]
(most-inspected data (fn [item] (quot item 3)) 20))
(def part-1 (most-inspected1 data))
;; => 110888
(defn most-inspected2 [data]
(most-inspected data (let [divisors (reduce * (map :divisor data))] ;; all are primes!
(fn [item] (mod item divisors))) 10000))
(def part-2 (most-inspected2 data))
;; => 25590400731