This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-12
Channels
- # adventofcode (42)
- # aleph (10)
- # announcements (1)
- # asami (138)
- # babashka (7)
- # beginners (7)
- # biff (13)
- # cider (7)
- # clj-kondo (15)
- # clojure (53)
- # clojure-austin (11)
- # clojure-belgium (2)
- # clojure-europe (23)
- # clojure-nl (1)
- # clojure-norway (55)
- # clojure-sweden (5)
- # clojure-uk (4)
- # cryogen (7)
- # cursive (63)
- # datomic (5)
- # eastwood (6)
- # emacs (31)
- # fulcro (7)
- # hyperfiddle (9)
- # introduce-yourself (3)
- # java (11)
- # lsp (10)
- # malli (14)
- # membrane (35)
- # off-topic (13)
- # portal (12)
- # prelude (1)
- # releases (2)
- # ring-swagger (27)
- # shadow-cljs (8)
- # timbre (25)
Day 12 - Solutions 🤯
https://github.com/erdos/advent-of-code/blob/master/2023/day12.clj
memoize
can help speed up the recursive calls. This seems to be a dynamic programming problem, where we can quickly match the prefix of a pattern, and then recursively process all the possible suffixes of the remaining pattern as well.
yeah this one was easy just wrap the whole thing in memoize
Sidenote, no idea why it takes 26ms to fetch a memoized solution…
(time (p2 input))
"Elapsed time: 26.741197 msecs"
when objects are not identical, you have to determine value equality. for big objects this can entail walking the entire object graph. not sure if that is into play here but could be
@U2E1D7WUB’s solution in https://squint-cljs.github.io/cherry/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa6e9992b079e20e21d753e8c75a7353c5908b225%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4Cgo7OyBSZW1lbWJlciB0byB1cGRhdGUgdGhlIHllYXIgYW5kIGRheSBpbiB0aGUgZmV0Y2gtaW5wdXQgY2FsbC4KKGRlZiBsaW5lcyAoLT4%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAxMikpCiAgICAgICAgICAgICBzdHIvc3BsaXQtbGluZXMpKQoKKGRlZm4gcGFyc2UtbGluZSBbbGluZV0KICAobGV0IFtbcm93IG5yc10gKC5zcGxpdCBsaW5lICIgIildCiAgICBbKHN0ciAoLnJlcGxhY2VBbGwgcm93ICJcXC5cXC4rIiAiLiIpKQogICAgIChtYXAgcGFyc2UtbG9uZyAoLnNwbGl0IG5ycyAiLCIpKV0pKQoKKGRlZm4gdmFsaWQtc3VmZml4ZXMgW3JvdyBudW1iZXJdCiAgKGZvciBbaSAocmFuZ2UgKGluYyAoLSAoY291bnQgcm93KSBudW1iZXIpKSkKICAgICAgICA6d2hpbGUgKGV2ZXJ5PyAje1wuIFw%2FfSAodGFrZSBpIHJvdykpCiAgICAgICAgOndoZW4gKGV2ZXJ5PyAje1wjIFw%2FfSAodGFrZSBudW1iZXIgKGRyb3AgaSByb3cpKSkKICAgICAgICA6d2hlbiAoI3tcLiBcP30gKG50aCByb3cgKCsgaSBudW1iZXIpIFwuKSldCiAgICAoZHJvcCAoKyBpIG51bWJlciAxKSByb3cpKSkKCihkZWZuIGFjcyBbcm93IG51bWJlcnNdCiAgKGlmLWxldCBbW24gJiBucnNdIChzZXEgbnVtYmVycyldCiAgICAocmVkdWNlICsgKGZvciBbcyAodmFsaWQtc3VmZml4ZXMgcm93IG4pXSAoYWNzIHMgbnJzKSkpCiAgICAoaWYgKGV2ZXJ5PyAje1wuIFw%2FfSByb3cpIDEgMCkpKQoKKGRlZiBhY3MgKG1lbW9pemUgYWNzKSkKCjs7IHBhcnQgMQooY29tbWVudAogICgtPj4gbGluZXMKICAgIChtYXAgcGFyc2UtbGluZSkKICAgIChtYXAgKHBhcnRpYWwgYXBwbHkgYWNzKSkKICAgIChyZWR1Y2UgKykKICAgICh0aW1lKSkpCgooZGVmbiAqNSBbW2xpbmUgcnVsZV1dCiAgWyhzdHIvam9pbiAiPyIgKHJlcGVhdCA1IGxpbmUpKQogICAoYXBwbHkgY29uY2F0IChyZXBlYXQgNSBydWxlKSldKQoKOzsgcGFydCAyCihjb21tZW50CiAgKGFzLT4gbGluZXMgJAogICAgKG1hcCBwYXJzZS1saW5lICQpCiAgICAobWFwICo1ICQpCiAgICAobWFwIChwYXJ0aWFsIGFwcGx5IGFjcykgJCkKICAgIChyZWR1Y2UgKyAkKQogICAgKGpzLWF3YWl0ICQpCiAgICAodGltZSAkKSkp
I tried to use https://github.com/bruceon/jsworkers for pmap
but couldn't get it to work in just the browser with dynamic import etc
Caching solution, 230ms.
(ns day12
(:require [clojure.string :as str]
[clojure.java.io :as io]))
(def lines (line-seq (io/reader "2023/day12.txt")))
(def parsed
(for [line lines]
(let [[field hints] (str/split line #" ")]
[(str "." (str/join "?" (repeat 5 field)) ".")
(vec (apply concat (repeat 5 (map parse-long (str/split hints #",")))))]
#_[(str "." field ".") (map parse-long (str/split hints #","))])))
(defn variants [[^String field, hints]]
(let [cache (volatile! {})]
(letfn [(f [i j start c]
(let [key (+ (* 10000 i) j)]
(or (and (nil? c) (nil? start) (@cache key))
(let [c (or c (when (< i (.length field))
(.charAt field i)))]
(case c
nil (if (= j (count hints)) 1 0)
\. (if start
(let [len (- i start)]
(if (= len (nth hints j nil))
(recur (inc i) (inc j) nil nil)
0))
(recur (inc i) j nil nil))
\# (recur (inc i) j (or start i) nil)
\? (let [res (+ (f i j start \.)
(f i j start \#))]
(when (nil? start)
(vswap! cache assoc key res))
res))))))]
(f 0 0 nil nil))))
(defn task2 []
(time (reduce + (map variants parsed))))
@U06PNK4HG’s solution https://squint-cljs.github.io/cherry/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa6e9992b079e20e21d753e8c75a7353c5908b225%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4Cjs7IFJlbWVtYmVyIHRvIHVwZGF0ZSB0aGUgeWVhciBhbmQgZGF5IGluIHRoZSBmZXRjaC1pbnB1dCBjYWxsLgooZGVmIGxpbmVzICgtPj4gKGpzLWF3YWl0IChmZXRjaC1pbnB1dCAyMDIzIDEyKSkKICAgICAgICAgICAgIHN0ci9zcGxpdC1saW5lcykpCgooZGVmIHBhcnNlZAogIChmb3IgW2xpbmUgbGluZXNdCiAgICAobGV0IFtbZmllbGQgaGludHNdIChzdHIvc3BsaXQgbGluZSAjIiAiKV0KICAgICAgWyhzdHIgIi4iIChzdHIvam9pbiAiPyIgKHJlcGVhdCA1IGZpZWxkKSkgIi4iKQogICAgICAgKHZlYyAoYXBwbHkgY29uY2F0IChyZXBlYXQgNSAobWFwIHBhcnNlLWxvbmcgKHN0ci9zcGxpdCBoaW50cyAjIiwiKSkpKSldCiAgICAgICNfWyhzdHIgIi4iIGZpZWxkICIuIikgKG1hcCBwYXJzZS1sb25nIChzdHIvc3BsaXQgaGludHMgIyIsIikpXSkpKQoKKGRlZm4gdmFyaWFudHMgW1teU3RyaW5nIGZpZWxkLCBoaW50c11dCiAgKGxldCBbY2FjaGUgKGF0b20ge30pXQogICAgKGxldGZuIFsoZiBbaSBqIHN0YXJ0IGNdCiAgICAgICAgICAgICAgKGxldCBba2V5ICgrICgqIDEwMDAwIGkpIGopXQogICAgICAgICAgICAgICAgKG9yIChhbmQgKG5pbD8gYykgKG5pbD8gc3RhcnQpIChAY2FjaGUga2V5KSkKICAgICAgICAgICAgICAgICAgICAobGV0IFtjIChvciBjICh3aGVuICg8IGkgKC4tbGVuZ3RoIGZpZWxkKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKC5jaGFyQXQgZmllbGQgaSkpKV0KICAgICAgICAgICAgICAgICAgICAgIChjYXNlIGMKICAgICAgICAgICAgICAgICAgICAgICAgbmlsIChpZiAoPSBqIChjb3VudCBoaW50cykpIDEgMCkKICAgICAgICAgICAgICAgICAgICAgICAgXC4gKGlmIHN0YXJ0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxldCBbbGVuICgtIGkgc3RhcnQpXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlmICg9IGxlbiAobnRoIGhpbnRzIGogbmlsKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlY3VyIChpbmMgaSkgKGluYyBqKSBuaWwgbmlsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXIgKGluYyBpKSBqIG5pbCBuaWwpKQogICAgICAgICAgICAgICAgICAgICAgICBcIyAocmVjdXIgKGluYyBpKSBqIChvciBzdGFydCBpKSBuaWwpCiAgICAgICAgICAgICAgICAgICAgICAgIFw%2FIChsZXQgW3JlcyAoKyAoZiBpIGogc3RhcnQgXC4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZiBpIGogc3RhcnQgXCMpKV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2hlbiAobmlsPyBzdGFydCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzd2FwISBjYWNoZSBhc3NvYyBrZXkgcmVzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMpKSkpKSldCiAgICAgIChmIDAgMCBuaWwgbmlsKSkpKQoKKGRlZm4gdGFzazIgW10KICAodGltZSAocmVkdWNlICsgKG1hcCB2YXJpYW50cyBwYXJzZWQpKSkp - somehow the squint version doesn't work properly, gonna check now
takes about 1.5 sec
It tries to match the whole group in one step. So if you have 3
as group count it will try to remove prefix of 3 ?
or #
and an additional .
or ?
, immediately returning 0 if not able.
Probably could make it faster by accessing string characters by index, instead of using string as a seq, but the code would be way uglier
https://github.com/rjray/advent-2023-clojure/blob/master/src/advent_of_code/day12.clj
Solved part 1 with brute force, then did a little analysis on how big part 2 was. Chose to sleep. Today, due to time-constraints, I just adapted a DP solution from some Python. I knew it needed to be a DP solution with memoize
, but it was this or spend hours reviewing my DP notes...
@U06PNK4HG’s solution in https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa6e9992b079e20e21d753e8c75a7353c5908b225%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4Cgo7OyBvcmlnaW5hbCBzb2x1dGlvbiBieSBAYWxleHlha3VzaGV2Cgo7OyBSZW1lbWJlciB0byB1cGRhdGUgdGhlIHllYXIgYW5kIGRheSBpbiB0aGUgZmV0Y2gtaW5wdXQgY2FsbC4KKGRlZiBsaW5lcyAoLT4%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAxMikpCiAgICAgICAgICAgICBzdHIvc3BsaXQtbGluZXMpKQoKKGRlZiBwYXJzZWQKICAodmVjIChmb3IgW2xpbmUgbGluZXNdCiAgICAgICAgIChsZXQgW1tmaWVsZCBoaW50c10gKHN0ci9zcGxpdCBsaW5lICMiICIpXQogICAgICAgICAgIFsoc3RyICIuIiAoc3RyL2pvaW4gIj8iIChyZXBlYXQgNSBmaWVsZCkpICIuIikKICAgICAgICAgICAgKHZlYyAoYXBwbHkgY29uY2F0IChyZXBlYXQgNSAobWFwIHBhcnNlLWxvbmcgKHN0ci9zcGxpdCBoaW50cyAjIiwiKSkpKSldCiAgICAgICAgICAgI19bKHN0ciAiLiIgZmllbGQgIi4iKSAobWFwIHBhcnNlLWxvbmcgKHN0ci9zcGxpdCBoaW50cyAjIiwiKSldICkpKSkKCihkZWZuIHZhcmlhbnRzIFtbXlN0cmluZyBmaWVsZCxoaW50c11dCiAgKGxldCBbY2FjaGUge31dCiAgICAobGV0Zm4gWyhmIFtpIGogc3RhcnQgY10KICAgICAgICAgICAgICAobGV0IFtjIChvciBjIG5pbCkKICAgICAgICAgICAgICAgICAgICBrZXkgKCsgKCogMTAwMDAgaSkgaildCiAgICAgICAgICAgICAgICAob3IgKGFuZCAobmlsPyBjKSAobmlsPyBzdGFydCkgKGdldCBjYWNoZSBrZXkpKQogICAgICAgICAgICAgICAgICAobGV0IFtjIChvciBjICh3aGVuICg8IGkgKC4tbGVuZ3RoIGZpZWxkKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICguY2hhckF0IGZpZWxkIGkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmlsKV0KICAgICAgICAgICAgICAgICAgICAoaWYtbm90IGMgKGlmICg9IGogKGNvdW50IGhpbnRzKSkgMSAwKQogICAgICAgICAgICAgICAgICAgICAgKGNhc2UgYwogICAgICAgICAgICAgICAgICAgICAgICBcLiAoaWYgc3RhcnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxldCBbbGVuICgtIGkgc3RhcnQpXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpZiAoPSBsZW4gKG50aCBoaW50cyBqIG5pbCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXIgKGluYyBpKSAoaW5jIGopIG5pbCBuaWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlY3VyIChpbmMgaSkgaiBuaWwgbmlsKSkKICAgICAgICAgICAgICAgICAgICAgICAgXCMgKHJlY3VyIChpbmMgaSkgaiAob3Igc3RhcnQgaSkgbmlsKQogICAgICAgICAgICAgICAgICAgICAgICBcPyAobGV0IFtyZXMgKCsgKGYgaSBqIHN0YXJ0IFwuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGYgaSBqIHN0YXJ0IFwjKSldCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh3aGVuIChuaWw%2FIHN0YXJ0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhc3NvYyEgY2FjaGUga2V5IHJlcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcykpKSkpKSldCiAgICAgIChmIDAgMCBuaWwgbmlsKSkpKQoKKGRlZm4gdGFzazIgW10KICAodGltZSAocmVkdWNlICsgKG1hcCB2YXJpYW50cyBwYXJzZWQpKSkp
I hate it... Three complete rewrites for part 2... https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2023/day12.clj
@U06PNK4HG do you have your part 1 also somewhere? I'd like to include it in the squint hall of fame solutions ;)
Actually, here https://gist.github.com/alexander-yakushev/7f40fbafa4fa29b93706ca823be4250a
@U06PNK4HG https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa6e9992b079e20e21d753e8c75a7353c5908b225%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4Cgo7OyBvcmlnaW5hbCBzb2x1dGlvbiBieSBAYWxleHlha3VzaGV2Cgo7OyBSZW1lbWJlciB0byB1cGRhdGUgdGhlIHllYXIgYW5kIGRheSBpbiB0aGUgZmV0Y2gtaW5wdXQgY2FsbC4KKGRlZiBsaW5lcyAoLT4%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAxMikpCiAgICAgICAgICAgICBzdHIvc3BsaXQtbGluZXMpKQoKKGRlZm4gcGFyc2UgW3Rhc2tdCiAgKHZlYyAoZm9yIFtsaW5lIGxpbmVzXQogICAgICAgICAobGV0IFtbZmllbGQgaGludHNdIChzdHIvc3BsaXQgbGluZSAjIiAiKV0KICAgICAgICAgICAoY2FzZSB0YXNrCiAgICAgICAgICAgICAxIFsoc3RyICIuIiBmaWVsZCAiLiIpIChtYXAgcGFyc2UtbG9uZyAoc3RyL3NwbGl0IGhpbnRzICMiLCIpKV0KICAgICAgICAgICAgIDIgWyhzdHIgIi4iIChzdHIvam9pbiAiPyIgKHJlcGVhdCA1IGZpZWxkKSkgIi4iKQogICAgICAgICAgICAgICAgKGludG8gW10gKGFwcGx5IGNvbmNhdCAocmVwZWF0IDUgKG1hcCBwYXJzZS1sb25nIChzdHIvc3BsaXQgaGludHMgIyIsIikpKSkpXSkpKSkpCgooZGVmbiB2YXJpYW50cyBbW15TdHJpbmcgZmllbGQsaGludHNdXQogIChsZXQgW2NhY2hlIHt9XQogICAgKGxldGZuIFsoZiBbaSBqIHN0YXJ0IGNdCiAgICAgICAgICAgICAgKGxldCBba2V5ICgrICgqIDEwMDAwIGkpIGopXQogICAgICAgICAgICAgICAgKG9yIChhbmQgKG5pbD8gYykgKG5pbD8gc3RhcnQpIChnZXQgY2FjaGUga2V5KSkKICAgICAgICAgICAgICAgICAgKGxldCBbYyAob3IgYyAod2hlbiAoPCBpICguLWxlbmd0aCBmaWVsZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoLmNoYXJBdCBmaWVsZCBpKSkpXQogICAgICAgICAgICAgICAgICAgIChpZi1ub3QgYyAoaWYgKD0gaiAoY291bnQgaGludHMpKSAxIDApCiAgICAgICAgICAgICAgICAgICAgICAoY2FzZSBjCiAgICAgICAgICAgICAgICAgICAgICAgIFwuIChpZiBzdGFydAogICAgICAgICAgICAgICAgICAgICAgICAgICAobGV0IFtsZW4gKC0gaSBzdGFydCldCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlmICg9IGxlbiAobnRoIGhpbnRzIGogbmlsKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZWN1ciAoaW5jIGkpIChpbmMgaikgbmlsIG5pbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXIgKGluYyBpKSBqIG5pbCBuaWwpKQogICAgICAgICAgICAgICAgICAgICAgICBcIyAocmVjdXIgKGluYyBpKSBqIChvciBzdGFydCBpKSBuaWwpCiAgICAgICAgICAgICAgICAgICAgICAgIFw%2FIChsZXQgW3JlcyAoKyAoZiBpIGogc3RhcnQgXC4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZiBpIGogc3RhcnQgXCMpKV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdoZW4gKG5pbD8gc3RhcnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFzc29jISBjYWNoZSBrZXkgcmVzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzKSkpKSkpKV0KICAgICAgKGYgMCAwIG5pbCBuaWwpKSkpCgooZGVmbiBzb2x2ZSBbdGFza10KICAodGltZSAocmVkdWNlICsgKG1hcCB2YXJpYW50cyAocGFyc2UgdGFzaykpKSkpCgojXyhzb2x2ZSAxKSAKI18oc29sdmUgMik%3D - still have to add the cat
transducer
added it here now https://github.com/squint-cljs/squint/blob/main/examples/aoc/solutions.md
yeah I made it way faster by making the function use indexes instead of sequences (which affects memoize speed).
but the code is way uglier
Manual memoization with local atom, 450 msec
(defn process-row [s]
(let [[s v] (str/split s #"\s+" 2)
s (->> s (repeat 5) (str/join "?"))
v (->> v (repeat 5) (str/join ","))
v (read-string (str "[" v "]"))
dp (atom {})
go (fn go [si vi]
(cond (>= vi (count v)) (if (str/index-of s \# si) 0 1)
(>= si (count s)) 0
:else (let [dp-k (+ vi (* 10000 si))]
(or (get @dp dp-k)
(let [n (get v vi)
dot-i (or (str/index-of s \. si) (count s))
r (+ (if (or (<= si dot-i (+ si n -1))
(= \# (get s (+ si n))))
0
(go (+ si n 1) (inc vi)))
(if (= \# (get s si))
0
(go (inc si) vi)))]
(swap! dp assoc dp-k r)
r)))))]
(go 0 0)))
(->> input
str/split-lines
(map process-row)
(apply +))
My https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2023/day_12.clj. I’m on a business trip on the east coast and, sadly, not much time to work on these.
if you care about performance, why use atom and persistent map to cache things? Why not use java.util.Hashmap?
Day 12 beat me up a bit for not thinking more about the problem first. https://github.com/bhauman/adv2023/blob/main/src/adv2023/day12/sol.clj
Are there any weird edge cases? I am pretty sure that my solution works and it looks right in all cases I picked. But for some reason it tells me the result is too low - so I wonder if I missed something specific in the input.
Day 1 - 10 using a lot of instaparse … https://github.com/danielneal/advent-of-code-2023/tree/main/src Not even going to look at Day 11, better quit now, as day 10 took me most of Sunday ha.
I considered using instaparse for day 2.... but ended up with several lines of replace
etc. instead.
I enjoyed how it reveals the structure of the input each time - I personally think you can look at it a grammar and get a feel for what the input looks like more easily than reading combinations of regexes