This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-13
Channels
- # adventofcode (54)
- # aleph (1)
- # announcements (2)
- # aws (123)
- # babashka (1)
- # beginners (41)
- # calva (21)
- # cider (1)
- # clj-kondo (58)
- # cljdoc (4)
- # clojure (123)
- # clojure-austin (1)
- # clojure-belgium (6)
- # clojure-dev (11)
- # clojure-europe (33)
- # clojure-nl (1)
- # clojure-portugal (1)
- # clojure-uk (3)
- # clojurescript (20)
- # community-development (32)
- # conjure (1)
- # datomic (17)
- # etaoin (8)
- # events (1)
- # fulcro (1)
- # hyperfiddle (7)
- # malli (3)
- # nrepl (3)
- # off-topic (17)
- # other-languages (1)
- # polylith (4)
- # portal (7)
- # releases (3)
- # remote-jobs (1)
- # shadow-cljs (18)
- # test-check (24)
- # testing (3)
- # timbre (1)
- # xtdb (7)
Day 13 - Solutions
not the most elegant comparison function, but I tried for speed today
it was also nice having an input file that was valid clojure
Very crude solution which I will proceed to refine. https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2022/day_13_distress_packets.clj
https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day13/main.clj Some days I feel like I have no reading comprehension skill....
parsing is easy if we wrap everything into a vector and read edn. Comparator is the meat of the task. I've made a detour trying to normalize packets to the same shape in order to use standard compare
, but figured that writing comparator is easier. https://github.com/nbardiuk/adventofcode/blob/master/2022/src/day13.clj
I got mine to work, also using edn/read-string
, and I've done my usual write-up.
• https://github.com/abyala/advent-2022-clojure/blob/main/docs/day13.md
• https://github.com/abyala/advent-2022-clojure/blob/main/src/advent_2022_clojure/day13.clj
Pretty gross comparator.. I basically wrote it while reading the puzzle text top-down. Was pleasently surprised to find that in part-2, I could slot it into clojure.core/sort
without any changes.
https://github.com/Ramblurr/advent-of-code/blob/main/src/aoc/2022/day13.clj
https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2022/13.clj no surprises today
(edn/read-string (str "[" input "]"))
doens't this somehow feel like some win condition for lisp?I don't think I've done anything very differently to anyone else here. Feels like this problem designed to be solved with a lisp.... Wonder if my comparator is a bit verbose... https://github.com/wardle/aoc2022/blob/main/src/day13.clj
Just read @UTFAPNRPT’s solution and his use of keep-indexed which is much nicer than my map-indexed and then filter contortions! This is great for learning.
https://github.com/FelipeCortez/advent-of-code/blob/master/2022/13.clj
and TIL
> Java comparators are all 3-way, meaning they return a negative, 0, or positive integer depending upon whether the first argument should be considered less than, equal to, or greater than the second argument.
>
> In Clojure, you may also use boolean comparators that return true
if the first argument should come before the second argument, or false
otherwise (i.e. should come after, or it is equal). The function <
is a perfect example, as long as you only need to compare numbers. >
works for sorting numbers in decreasing order. Behind the scenes, when such a Clojure function bool-cmp-fn
is "called as a comparator", Clojure runs code that works like this to return an int instead:
>
(if (bool-cmp-fn x y)
> -1 ; x < y
> (if (bool-cmp-fn y x) ; note the reversed argument order
> 1 ; x > y
> 0)) ; x = y
Recommended reading on clojure comparators: https://clojure.org/guides/comparators
[2,3,4] vs 4 are in the right order
because 2<4 makes a decision before right runs out of elements.
so [2 3 4] [4] is ok
and [2 3 4] [2] is not because 2=2 (no decision), and only after that right runs out of elements
and [2] [2 3 4] is ok, because 2=2 (no decision), and left runs out, and thats ok
and as a result (every? true? (map correct? left right))
is incorrectMuch much easier than yesterday... It was great decision to write comparator for part1. https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2022/day13.clj
The interesting bit
(defn comparer [a b]
(cond
(every? integer? [a b])
(compare a b)
(every? sequential? [a b])
(if-let [res (->> (map comparer a b) (filter #(not (zero? %))) first)]
res
(comparer (count a) (count b)))
:else ;; one is a list and one is an integer
(apply comparer (map #(cond-> % (integer? %) vector) [a b]))))
Lists, first, next. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d13.clj
Looking at the source for =
led me to next
instead of rest
, which I always forget about. next
especially helps because (compare nil 2 ) (compare 3 nil) (compare nil nil)
all do the right thing.
That’s a good thing to remember, @U1Z392WMQ.
Mine is a bit wordy https://github.com/zelark/AoC-2022/blob/master/src/zelark/aoc_2022/day_13.clj
I thought a lot about it (too much!) and made two attempts to normalize and flatten the packets and do a simple element-wise compare, but I kept running into exceptions. I got as close as having only 3 cases that I couldn’t resolve (with my input). Ah well. It’s like the false promise of alchemy.
made an animation how the packets would look like if normalized to the common shape. Although it is only animation, the compare
doesn't work on it
nil
is less than everything, ##-Inf
is less than everything else, and ##NaN
is less than nothing.
nil is endless void ^_^
Day 13 part 1: I get the right answer for the sample, but it’s wrong for my input. Any tips?
double checked everything, but can’t see a mistake
compared visually the output for every example, it seems correct
The input has empty vectors in strange places that messed me up when I tried to get too tricky.
I use edn/read-string
to parse it, should work fine I guess
(read-string (str "[" input "]"))
(partition 2)
works fine for the example and the real input also seems correct. Am I wrong?should be fine, I found a problem with a logic for comparison
I’m using a zipper in a wrong way
(cmp [[[] 6 2]] [[[]] [10]])
a good example to check against, should return false
My mistake is I was trying to use zippers.
Posting out here to see if someone with clojure-core-match
skills can answer a specific question on my solution to day 13.
In the bottom of https://github.com/abyala/advent-2022-clojure/blob/main/docs/day13.md, I mention trying to use match
to check the types of the two values at a given level of the vector, checking if they're nil
, scalar, or vectors. I was able to work with matching on [(type v)]
just fine, but once I brought in two types, with [(type v1) (type v2)]
, I couldn't get it to work. I had to resort to :guard
clauses, which just look messy.
Does anyone know how to get the matcher to work when using the types of 2 or more values in the input vector?
I started on the same approach! I just went with condp
in the end which does the same thing in this trivial case
I had the same idea, but when I saw this in the wiki, I gave up on match as more complex.
> Unlike pattern matching found in most functional programming languages core.match
does not promote matching on concrete types. Instead core.match
matches on abstract interfaces / protocols -`IPersistentVector`, ILookup
, Sequential
and so on.
I found a way to make it work, but I still think it's messy. Instead of working with actual types, I had to map the types to keywords. Note the mapv
under the m/match
call. Surely this isn't the intention?
(defn correct-order?
([left right] (correct-order? left right [0]))
([left right address]
(let [[v1 v2 :as values] (map #(get-in % address) [left right])]
(m/match (mapv #(cond (number? %) :num, (vector? %) :vec, :else nil) values)
[nil nil] (recur left right (-> address move-up move-right))
[nil _] true
[_ nil] false
[:num :num] (case (u/signum (- v1 v2))
-1 true
1 false
(recur left right (move-right address)))
[:vec :vec] (recur left right (move-down address))
[:vec :num] (recur left (vectorize right address) address)
[:num :vec] (recur (vectorize left address) right address)))))
why not use guards for types?
@U01V2D5ALKX - I did the first time through, but I had to repeat the guards multiple times to get all of the conditions to work. Thought it looked a little ugly, unless you know a better way.
(defn correct-order?
([left right] (correct-order? left right [0]))
([left right address]
(let [[v1 v2] (map #(get-in % address) [left right])]
(m/match [v1 v2]
[nil nil] (recur left right (-> address move-up move-right))
[nil _] true
[_ nil] false
[(_ :guard number?) (_ :guard number?)] (case (u/signum (- v1 v2))
-1 true
1 false
(recur left right (move-right address)))
[(_ :guard vector?) (_ :guard vector?)] (recur left right (move-down address))
[(_ :guard vector?) _] (recur left (vectorize right address) address)
[_ (_ :guard vector?)] (recur (vectorize left address) right address)))))