1
+ ^:kindly/hide-code
1
2
(ns y2024.d19
2
3
(:require
3
4
[advent-of-code-clj.input :as input]))
@@ -33,7 +34,7 @@ bbrgwb")
33
34
; mønstrene, og resten av duken matcher et mønster. Altså en rekursiv
34
35
; algritme:
35
36
36
- (defn valid-pattern? [patterns towel]
37
+ (defn valid-pattern? [patterns ^String towel]
37
38
(if (= " " towel)
38
39
true
39
40
(some
@@ -78,7 +79,7 @@ bbrgwb")
78
79
79
80
(def valid-patterns
80
81
(memoize
81
- (fn [patterns towel]
82
+ (fn [patterns ^String towel]
82
83
(if (= " " towel)
83
84
1
84
85
(transduce (map (fn [p]
@@ -101,3 +102,56 @@ bbrgwb")
101
102
(comment
102
103
(time
103
104
(part-2 (input/get-input 2024 19 ))))
105
+
106
+ ; ## Del 1 og 2 med typehints
107
+
108
+ ; Det viser seg at algoritmene egentlig ikke er så trege! Algoritmen bruker mye tid på reflection fordi
109
+ ; vi kaller `.startsWith` på en variabel som kompilatoren ikke kan garantere at alltid er en `String`.
110
+
111
+ ; Se [dokumentasjon om type hinting](https://clojure.org/reference/java_interop#typehints)
112
+
113
+ ; Når kjører koden med reflection-warning finner vi de to stedene som er særlig utsatt fordi de er i en
114
+ ; "hot loop":
115
+
116
+ ^:kind/hiccup
117
+ [:pre " (set! *warn-on-reflection* true)" ]
118
+
119
+ ^:kind/hiccup
120
+ [:pre " Reflection warning,... - call to method startsWith can't be resolved (target class is unknown)." ]
121
+
122
+ ; Hvis vi lager nye type-hintede versjoner av `valid-pattern`-algoritmene kuttes kjøretiden ned til et mer
123
+ ; akseptabelt nivå (~80ms og ~300ms):
124
+
125
+ (defn valid-pattern?-hinted [patterns ^String towel]
126
+ (if (= " " towel)
127
+ true
128
+ (some
129
+ (fn [p]
130
+ (when (.startsWith towel p)
131
+ (valid-pattern?-hinted patterns (subs towel (count p) (count towel)))))
132
+ patterns)))
133
+
134
+ (def valid-patterns-hinted
135
+ (memoize
136
+ (fn [patterns ^String towel]
137
+ (if (= " " towel)
138
+ 1
139
+ (transduce (map (fn [p]
140
+ (if (.startsWith towel p)
141
+ (valid-patterns-hinted patterns (subs towel (count p) (count towel)))
142
+ 0 )))
143
+ + patterns)))))
144
+
145
+ (defn part-1-hinted [input]
146
+ (let [[patterns towels] (parse input)]
147
+ (count (keep #(valid-pattern?-hinted patterns %)
148
+ towels))))
149
+
150
+ (delay (part-1-hinted (input/get-input 2024 19 )))
151
+
152
+ (defn part-2-hinted [input]
153
+ (let [[patterns towels] (parse input)]
154
+ (transduce (map #(valid-patterns-hinted patterns %))
155
+ + towels)))
156
+
157
+ (delay (part-2-hinted (input/get-input 2024 19 )))
0 commit comments