This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-09
Channels
- # adventofcode (93)
- # announcements (11)
- # babashka (7)
- # babashka-sci-dev (17)
- # beginners (73)
- # biff (7)
- # calva (3)
- # cider (1)
- # clj-kondo (160)
- # clj-together (12)
- # clojure (44)
- # clojure-art (2)
- # clojure-europe (12)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-norway (22)
- # clojure-uk (2)
- # clojurescript (8)
- # clr (1)
- # cursive (6)
- # data-science (1)
- # datomic (1)
- # emacs (6)
- # events (1)
- # exercism (1)
- # fulcro (6)
- # graphql (2)
- # introduce-yourself (1)
- # lsp (18)
- # nrepl (7)
- # off-topic (45)
- # polylith (25)
- # portal (25)
- # practicalli (3)
- # re-frame (14)
- # reagent (28)
- # reitit (2)
- # releases (2)
- # shadow-cljs (73)
- # sql (11)
- # tools-deps (12)
- # transit (4)
- # xtdb (4)
I'm learning so much from all your solutions! Thanks for posting everyone. A quick question from a day8 function I saw:
(defn visible?
[[tree & other-trees]]
(every? #(< % tree) other-trees))
This captures edges too without needing a single arity version, e.g. (visible? [3]) ;;=> true
but it's unclear to me what is happening with every? and the comparison when there's no other value to compare with. It's clearly not equivalent to (< (rest [3]) 3)
.other-trees
will be nil
when there are no args to destruct there. A way to investigate things like this is to use ”inline def”.
(defn visible?
[[tree & other-trees]]
(def tree tree)
(def other-trees other-trees)
(every? #(< % tree) other-trees))
Then call the function:
(visible? [3])
Then evaluate other-trees
in the REPL.Thanks for the response. I understand other-trees will be nil, but I don't understand how it doesn't reduce to the comparison (< nil 3)
and a NullPointerException, and what every? does with it.
Check out https://clojuredocs.org/clojure.core/every_q. In fact, I added a think about nil
there just a few days ago, because it surprised me too.
Aha! "vacuous truth"
The hypocrisy of i using eval
by other names, such as read-string
, is going on to this day, though.
Day 9 - Solutions
Am I the only fool staying up late to code this and document it? Oh well, so be it! Fun puzzle today. 🙂 • https://github.com/abyala/advent-2022-clojure/blob/main/docs/day09.md • https://github.com/abyala/advent-2022-clojure/blob/main/src/advent_2022_clojure/day09.clj
https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2022/09.clj early rather than late for me! agreed this was a fun one. getting more interesting now
https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day09/main.clj No - I stayed up too. I completely misunderstood the tail following head algorithm, but what I did worked for all sample inputs and the full input on part1 but not on part 2. After re-reading for the 47th time I finally figured out what I was doing wrong. uggghh.... I applies zero cleanup here, so it's a total mess
Now contains both parts. https://gist.github.com/maacl/992c94a6000ae1ae206a926eccd34294#file-clj
👋 new clojurian here. after a rough day 8, am decently pleased with my solution today. happy for any notes! https://github.com/elh/advent-2022/blob/main/src/advent_2022/day_09.clj
I reused my grid/moves->path
function which takes the input and returns all coords visited, made this trivial. Each subsequent knot treats the earlier knot like the head, so iterate
works nicely. Refactored with core.matrix, thanks @U02CV2P4J6S
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d09.clj

More verbose than I would like.. but I'm not golfing after all. https://github.com/Ramblurr/advent-of-code-2022/blob/main/src/aoc/day09.clj
https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2022/day9.clj (formatted it) feeling ultra clever today
@U02CV2P4J6S nice idea, I’m going to replace some of my vector helpers with core.matrix/{+,-}
now.
had a total brain freeze for some 10 minutes trying to come up with the generalized step fn reduction https://github.com/FelipeCortez/advent-of-code/blob/master/2022/09.clj
@U01HL2S0X71 shouldn't make much of a difference here but last
is linear, peek
is constant https://github.com/callum-oakley/advent-of-code/blob/b562459233253a8de222e96cc17de2af6e3a040d/src/aoc/2022/09.clj#L28e
@UA2U3KW0L good catch, thanks! cuts the time almost in half 😁 (from 200ms to 100ms)
I like your move-rope
implementation, @U076FM90B, since I was reducing over the indexes of my knot vector and calling update
for the values in place. I think your reduce
with conj
of a new vector is a much cleaner solution. Once I update my blog, I think I'll be following suit!
I took a shortcut for part 1 that slowed me down for part 2. In part one since the head only moves up down left or right, the tail, if it moves always takes the old head position. This doesn't work for part two though as intermediate knots might move diagonally.
here we go https://github.com/zelark/AoC-2022/blob/master/src/zelark/aoc_2022/day_09.clj
@U076FM90B as usual like your solution especially when it comes to moving something ^_^
btw, just checked that clojure.math
has signum
.
@U067R559Q cool! I've never seen it TIL
. Will try to integrate into next solutions
Yikes. Wasn't sure I liked this today. Bizarrely, my solution to the second part is simpler and more general purpose (configurable numbers of knots) than my solution to the second part! One of those times knowing the second part would have helped! https://github.com/wardle/aoc2022/blob/main/src/day09.clj
Think I need to learn 'iterate' given the posted solutions above!
Didn't know the clojure.core.matrix
so had to reinvent some wheels, it's not super readable though:
(defn -mapf [fc ac] (mapv #(%1 %2) fc ac))
(defn follow [H T]
(let [diff (map - H T)]
(if (> (apply max (map abs diff)) 1)
(let [fx (map #(cond (> % 0) inc (< % 0) dec :else *) diff)] (-mapf fx T))
T)))
(defn solve [input len]
(-> (reduce
(fn [{p :pos :as g} [m s]]
(let [go (partial -mapf ((zipmap ["R" "L" "U" "D"] [[inc *] [dec *] [* inc] [* dec]]) m))]
(loop [p p, n (parse-long s), g g]
(if (zero? n) (assoc g :pos p)
(let [np (reduce #(conj %1 (follow (last %1) %2)) [(go (first p))] (rest p))]
(recur np (dec n) (update g :vis #(conj % (last np)))))))))
{:pos (repeat len [0 0]), :vis #{[0 0]}} input)
:vis count))
(defn -main [day]
(let [solution (->> (file->str day) (re-seq #"\w+") (partition 2) (partial solve))]
{:part1 (solution 2) :part2 (solution 10)}))
Day 9 https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day9/sol.clj
whew, slightly ugly but here it goes:
(ns day9)
(def dirs {"U" [0 -1] "D" [0 1] "R" [1 0] "L" [-1 0]})
(def data (->> "input/day9.txt" slurp lines
(mapcat #(let [[d n] (split % " ")] (repeat (parse-long n) (dirs d))))
(reductions #(mapv + %1 %2) [0 0])))
(defn next-pos [[tx ty] [hx hy]]
(let [sign (fn [x] (cond (zero? x) x (< x 0) -1 :else 1))]
(if (or (-> tx (- hx) abs (> 1)) (-> ty (- hy) abs (> 1)))
[(+ tx (sign (- hx tx))) (+ ty (sign (- hy ty)))]
[tx ty])))
(let [paths (iterate (partial reductions next-pos) data)]
(println "1:" (->> paths second (map str) set count))
(println "2:" (->> (nth paths 9) (map str) set count)))
nailing next-pos
took me ages cause I've made a dumb assumptionMe too! Great to see other people's solutions for ideas!
also, my sets don't like vectors so I had to (map str)
, it wouldn't be needed in Clojure
so in the case of the snake of positions you only have to keep the last position in the accumulator
Yes I see - I went through contortions to track each step in my 'reduce' which would have been unnecessary!
Yup, that would make my solution much simpler
I feel I would be cheating now to change it, but will keep in mind for coming days. That said, I am not sure I can look at my day 9 code and not change it... ! 😂
Hey if it’s in git, everyone can see the history….. so change away. That’s what I do anyway. It’s not that often that you can have this much fun coding, so I say maximize the fun and experimenting.
I came up with my own solution this morning, but looking over others I like some of the simpler approaches (i.e. reductions instead of loop/recur). Maybe I’ll go back and re-factor, but good enough for now. https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2022/day_09_rope_snake.clj
An advantage to iterate/reductions is you have all this step-wise data for the visualizations that you’ll never make
Right... this is very much simpler - TIL reductions
is a super power. Updated code, still can be improved but good enough. https://github.com/wardle/aoc2022/blob/main/src/day09.clj
Haha, I had just discovered reductions
today also!
https://github.com/leinfink/aoc-2022-clj/blob/main/src/aoc22/day9.clj
Nearly got crazy until I realised it had \d
instead of \d+
in my regex so the latter parts of the input failed to parse correctly...
Reading through here, I wonder why it didn't occur to me to use reductions for the tail itself, and not just for the intermediate knots, as I did? :face_with_raised_eyebrow: Oh well, happy with my result 😇
Blergh. What an ugly solution I’ve written today. https://coyotesqrl.github.io/advent-of-code/2022/src/coyotesqrl/2022/day09.html
check if they are touching/overlap/neighbor
neighbor? (fn [xy1 xy2] (every? #{-1, 0, 1} (map - xy1 xy2)))
catch up to previous knot
(->> (map - prev curr)
(map #({2 1, -2 -1} % 0))
(map - prev))
Happy Friday yous lot :)) I had fun taking https://github.com/mikera/core.matrix for a spin, for the first time! https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2022/d9.clj
https://clojurians.slack.com/archives/C0GLTDB2T/p1670624488987059?thread_ts=1670570395.443139&cid=C0GLTDB2T oh that could clean up my next-pos
nicely, thanks Apple
@UP82LQR9N what a nice and neat solution
Eventually made it https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2022/day09.clj
Also visualized how to knots travel. First knot and ninth knot (blues are knots from 1-8)
this visualization reminds me that people come up with part 3: what's the smallest number of knots such that the tail knot doesn't move
https://www.reddit.com/r/adventofcode/comments/zgre9m/2022_day_9_bonus_mini_problem_only_try_after_part/
very late to the game but finally got around to finishing day 09:
(ns aoc.day-09)
(let [ds {\L [0 -1] \R [0 1] \U [-1 0] \D [1 0]}
parse (fn [a [d n]] (concat a (repeat (parse-long n) (ds (first d)))))
data (reduce parse [] (partition 2 (re-seq #"\w+" (slurp "data/2022_09"))))
head (reductions #(mapv + %1 %2) [0 0] data)
rope (fn [[y x :as t] h]
(let [[dy dx] (map - h t)
tx {0 0 2 1 -2 -1}]
[(+ y (tx dy ({2 dy} (abs dx) 0))) (+ x (tx dx ({2 dx} (abs dy) 0)))]))
tail #(reductions rope [0 0] %)]
(prn {:one (count (distinct (tail head)))
:two (count (distinct (nth (iterate #(tail %) head) 9)))}))
Same here. I also made a visualization, mainly to verify my solution and because I want to get used to writing SVG. However, ran into stack overflow with the actual data, so I guess canvas would have been a better choice here. 🙂 https://github.clerk.garden/formsandlines/aoc2022-clojure/commit/a068cdff5c85be281f7bf550313d5e9a2b05d573/src/advent_of_clerk/day_09.html

Omg, reductions
would have made my life so much easier (it seems like I am not the only one, looking at this thread). Also, I really like the approach of using map
for simple vector math that I have seen in some solutions. I also have to remember to make more clever use of default values in collection getters.
Anyone know if there's an easy way to pair clerk and quil for simple web based visualizations?
maybe people in #C035GRLJEP8 can help. I guess there should be a way to assign custom visualiser for data based on its metadata, but I haven't looked into it.
I think Quil has been lagging way behind on jvm versions… it only works on jdk8 etc as far as I know
but if you are interested in Mathbox I can get you set up with Clerk and mathbox! https://mathbox.mentat.org/
mathbox examples: https://mathbox.org/
> I think Quil has been lagging way behind on jvm versions… it only works on jdk8 etc as far as I know Oh that's sad.. I haven't used it in quite a few years. But I thought it might be fun to use with this years AOC since there are some cool animated visualizations one can do. And since I've been using Clerk notebooks for AoC I thought it would be cool to pair them. I've also never used Quil in a web browser context, so not sure how that would work
Actually!! That might be totally fine since the cljs side uses p5.js which is up to date
ChatGPT likes you! I ask it what's the date today and all I get is 'no data', 'trained till 2021'
I pasted the solution for my day 5 and asked for it to explain in human terms what it was doing. Not only did it figure out that it was an Advent of Code Day 5 solution (good namespace?) but also explained what the code was doing using words such as warehouse that weren't present in the solution. https://github.com/marceloschreiber/advent-of-code-clojure/tree/main/src/aoc/2022/day_05 (kind of hard to read)