This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-14
Channels
- # adventofcode (29)
- # aws (3)
- # babashka (25)
- # beginners (13)
- # calva (4)
- # cherry (7)
- # cider (26)
- # clj-kondo (9)
- # clojure (88)
- # clojure-europe (21)
- # clojure-losangeles (3)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (11)
- # clojuredesign-podcast (2)
- # clojurescript (4)
- # cursive (10)
- # datalevin (1)
- # emacs (50)
- # gratitude (1)
- # honeysql (12)
- # hyperfiddle (19)
- # jobs-discuss (28)
- # kaocha (3)
- # lsp (53)
- # malli (4)
- # meander (3)
- # off-topic (48)
- # re-frame (11)
- # releases (2)
- # ring-swagger (2)
- # shadow-cljs (50)
- # squint (26)
- # tools-build (3)
- # tools-deps (8)
- # xtdb (4)
- # yamlscript (1)
I can’t reply to the thread… tried restarting app. Maybe there is a cache thats fouling things up
Solution: https://github.com/erdos/advent-of-code/blob/master/2023/day14.clj My approach is quite slow due to transposing the data back an forth all the time, so there is a lot to improve. The trick with part 2 is that the spin cycle becomes periodical after a while, so we just have to find that point as well as the length of periodicity.
I remember Tetris (Day 17: Pyroclastic Flow) last year — the same trick https://adventofcode.com/2022/day/17
Yet another slow solution (~4 secs) https://github.com/zelark/AoC/blob/master/src/zelark/aoc_2023/day_14.clj
Think of analog clocks. 😉
5 secs for part-2 https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2023/day14.clj
@UEF091BP0 could you mark this thread as a solution thread?
For the p.2 I assumed there will be some frequency finding in the cycles, so I didn't bother with the code and found it pretty quickly with some printing and pencil. Both solutions go in ~0.8 sec together 😛 https://github.com/caseneuve/aoc2023/blob/master/day14/solution.clj
A fast one, 3-5 ms for part 2 on the real input (Edited: sorry, flawed measurement)
https://github.com/gveres/advent-of-code-2023-clojure/blob/main/src/day14.clj
I'm pretty proud of the "line-tilt" ;
(defn tilt-left [line]
(->> line
(partition-by #(= % \#))
(mapcat (comp reverse sort))
(apply str)))
My Day 14 (4s) https://github.com/bhauman/adv2023/blob/main/src/adv2023/day14/sol.clj
@U4XJNL67P very very similar!
@U064J0EFR, yes it is very similar, cool, except your tilt is even more elegant 👍
I really like tilt
with partition-by
, but, interestingly, it makes my code run twice as long in comparison to my not so elegant loop
(cc @U064J0EFR, @U4XJNL67P) Also @U4XJNL67P, I tried your solution on my machine, but can't go under 3 sec with it.
https://github.com/rjray/advent-2023-clojure/blob/master/src/advent_of_code/day14.clj When I first wrote part 1, I tried to anticipate what part 2 would be. I was wrong, and to add insult to injury my part 1 took 20s to run. So I slept on it, and this morning I rewrote part 1, getting it to run in about 43ms. Part 2, once I had time to think about it, is a familiar pattern (there's usually one of these every year).
@UUAKPEMJ9, sounds weird, but thanks for reporting, I'll check again
@UUAKPEMJ9, my mistake - I accidentally measured with a pre-warmed memoized function in the REPL. I stand corrected - mea culpa.
Nice task! 830 ms for whole part 2 (150 rotation cycles in my case), after replacing immutable strings processing by mutable char-array
with aget & aset
by indexes
(let [ca (char-array input)
cols (str/index-of input \newline)
rows (quot (count input) cols)
lis (mapv (fn [r] (mapv #(+ % (* (inc cols) r)) (range cols))) (range rows))
ris (mapv (comp vec reverse) lis)
tis (mapv (fn [c] (mapv #(+ (* % (inc cols)) c) (range rows))) (range cols))
bis (mapv (comp vec reverse) tis)
swaps (fn [i j] (let [t (aget ca i)] (aset ca i (aget ca j)) (aset ca j t)))
process-line (fn [xs] (reduce (fn [iis i]
(let [c (aget ca i)]
(case c
\O (if (empty? iis)
iis
(do (swaps (first iis) i)
(conj (subvec iis 1) i)))
\# []
(conj iis i))))
[] xs))
move (fn [dir] (doseq [d dir] (process-line d)))
rotate (fn [] (move tis) (move lis) (move bis) (move ris))]
(doseq [_ (range 150)] (rotate))
(north-support (String. ca)))
My https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2023/day_14_v2.clj. I loaded the \O
and \#
into a locmap (keyed by [r c]
) and then for the cycles I did a rotation transformation on the keys of the locmap. I had a few spare moments in between meetings and rewrote my split-grouped-lines
and locmap<-
utility functions https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/common2.clj. I’m quite pleased with those.
To practice I wrote a stateful transducer to tilt one line. cut my time in half for part 2, but did not optimize the rest, so still 10sec total...
(def tilt-transducer
"transforms a line into sequences of the form OOO....# by remembering round rocks and dots until # is read (or end of line)"
(fn [rf]
(let [dots (volatile! 0)
rounds (volatile! 0)]
(fn ([] (rf))
([result] (let [tmp (concat (repeat @rounds \O) (repeat @dots \.))
result (if (empty? tmp)
result
(unreduced (rf result tmp)))]
(vreset! dots 0)
(vreset! rounds 0)
(rf result)))
([result input]
(condp = input
\. (do (vswap! dots inc) result)
\O (do (vswap! rounds inc) result)
\# (let [out (concat (repeat @rounds \O) (repeat @dots \.) '(\#))]
(vreset! dots 0)
(vreset! rounds 0)
(rf result out))
result))))))
(transduce tilt-transducer concat '(\# \. \O \O \. \O \# \. \O))
;=> (\# \O \O \O \. \. \# \O \.)
Still catching up over the week-end : https://github.com/arnaudgeiser/advent-of-code/blob/master/2023/clojure/src/advent_of_code/day14.clj
Updated my solution with some optimizations. It is still Clojure without fancy things and mutations, now it takes 730 msecs.
https://github.com/zelark/AoC/blob/master/src/zelark/aoc_2023/day_14.clj
For tilt
came up with this code
(defn tilt-part [^String part dir]
(if (str/blank? part)
part
(let [rocks (.repeat "O" (aoc/cnt part \O))
space (.repeat "." (aoc/cnt part \.))]
(case dir
:left (str rocks space)
:right (str space rocks)))))
(defn tilt-row [^String row dir]
(->> (str/split row #"#" -1)
(map #(tilt-part % dir))
(str/join "#")))
(defn tilt [platform dir]
(mapv #(tilt-row % dir) platform))
TIL about string.repeat
. It’s there since JDK 11. One more interesting thing — str/split
can accept 3rd argument — limit. If the limit is negative then the pattern will be applied as many times as possible and the array can have any length