adventofcode

Aleks 2022-12-13T19:03:24.648099Z

A funny fact: now we can apply packet comparator to https://adventofcode.com/2021/day/18. I did and it worked almost fine! Except, their magnitudes don’t keep the order.

Aleks 2022-12-13T19:03:33.670769Z

([[[0 [5 8]] [[1 7] [9 6]]] [[4 [1 2]] [[1 4] 2]]]
 [[2 [[7 7] 7]] [[5 8] [[9 3] [0 2]]]]
 [[[5 [2 8]] 4] [5 [[9 9] 0]]]
 [[[[5 2] 5] [8 [3 7]]] [[5 [7 5]] [4 4]]]
 [[[[5 4] [7 7]] 8] [[8 3] 8]]
 [6 [[[6 2] [5 6]] [[7 6] [4 7]]]]
 [[6 [[7 3] [3 2]]] [[[3 8] [5 7]] 4]]
 [[[6 [0 7]] [0 9]] [4 [9 [9 0]]]]
 [[[7 [6 4]] [3 [1 3]]] [[[5 5] 1] 9]]
 [[9 3] [[9 9] [6 [4 9]]]])

(1636 1346 1125 1565 1511 1342 1510 870 1317 681)

😆 1
Aleks 2022-12-13T21:20:00.003059Z

Wow! I am fucking right 😅

2022-12-13T05:40:08.744249Z

Day 13 - Solutions

wevrem 2022-12-13T08:10:33.173369Z

Okay, refining is done. Off to bed.

Casey 2022-12-13T08:40:09.789819Z

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

Callum Oakley 2022-12-13T09:12:38.662259Z

https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2022/13.clj no surprises today

Benjamin 2022-12-13T10:36:02.514529Z

(edn/read-string (str "[" input "]"))
doens't this somehow feel like some win condition for lisp?

Casey 2022-12-13T10:46:01.892139Z

Maybe.. in JavaScript you could so the same with JSON.parse

Mark Wardle 2022-12-13T11:39:45.138709Z

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

Mark Wardle 2022-12-13T11:50:29.406609Z

Just read @michaeljweaver’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.

➕ 2
Felipe 2022-12-13T12:10:18.652329Z

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

Casey 2022-12-13T12:11:12.923569Z

Recommended reading on clojure comparators: https://clojure.org/guides/comparators

misha 2022-12-13T14:23:47.807509Z

[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 incorrect

genmeblog 2022-12-13T15:05:59.611169Z

Much 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

bhauman 2022-12-13T15:45:00.665119Z

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]))))

✔️ 1
tschady 2022-12-13T15:45:39.617599Z

Lists, first, next. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d13.clj

tschady 2022-12-13T16:09:28.333519Z

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.

wevrem 2022-12-13T16:27:37.335889Z

That’s a good thing to remember, @tws.

Aleks 2022-12-13T16:34:33.754839Z

Impressed by @michaeljweaver’s code of comparator. It’s really concise.

🙏 1
Aleks 2022-12-13T16:35:07.263199Z

Mine is a bit wordy https://github.com/zelark/AoC-2022/blob/master/src/zelark/aoc_2022/day_13.clj

wevrem 2022-12-13T17:11:37.978429Z

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.

nbardiuk 2022-12-13T17:21:34.555129Z

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

2
🆒 2
Aleks 2022-12-13T21:02:04.935099Z

(compare nil ##-Inf) ; => -1 surprise!

bhauman 2022-12-13T21:44:22.235499Z

what did you put test.check on the case?

wevrem 2022-12-14T00:43:53.216479Z

Nil is less than everything. And ##-Inf is less than everything else.

tschady 2022-12-14T00:48:54.311239Z

not everything trollface

user=> (compare ##-Inf ##NaN)
0

🤪 1
2022-12-13T05:40:56.007919Z

not the most elegant comparison function, but I tried for speed today

2022-12-13T05:45:43.174009Z

it was also nice having an input file that was valid clojure

wevrem 2022-12-13T05:49:32.974699Z

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

🙌 1
2022-12-13T06:46:55.398309Z

https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day13/main.clj Some days I feel like I have no reading comprehension skill....

nbardiuk 2022-12-13T07:24:40.997709Z

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

Andrew Byala 2022-12-13T07:39:25.414189Z

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.mdhttps://github.com/abyala/advent-2022-clojure/blob/main/src/advent_2022_clojure/day13.clj

wevrem 2022-12-14T15:22:14.121919Z

nil is less than everything, ##-Inf is less than everything else, and ##NaN is less than nothing.

Aleks 2022-12-14T15:23:17.031239Z

nil is endless void ^_^

Aleks 2022-12-13T07:27:52.011249Z

Day 13 part 1: I get the right answer for the sample, but it’s wrong for my input. Any tips?

Benjamin 2022-12-13T09:28:24.805289Z

Came here for the exact same question

Benjamin 2022-12-13T09:31:53.873869Z

(read-string (str "[" input "]"))
   (partition 2)
works fine for the example and the real input also seems correct. Am I wrong?

Aleks 2022-12-13T09:43:05.179739Z

should be fine, I found a problem with a logic for comparison

Aleks 2022-12-13T09:43:39.325029Z

I’m using a zipper in a wrong way

Benjamin 2022-12-13T09:53:36.182439Z

For me I realized my logic is wrong for this case:

[[4, 5], 6]
[[4, 5], 3]

Aleks 2022-12-13T12:53:03.346969Z

(cmp [[[] 6 2]] [[[]] [10]]) a good example to check against, should return false

Aleks 2022-12-13T12:59:45.045049Z

My mistake is I was trying to use zippers.

Aleks 2022-12-13T07:31:33.935549Z

double checked everything, but can’t see a mistake

Aleks 2022-12-13T07:35:07.563799Z

compared visually the output for every example, it seems correct

wevrem 2022-12-13T07:35:53.964269Z

The input has empty vectors in strange places that messed me up when I tried to get too tricky.

Aleks 2022-12-13T07:41:16.819329Z

I use edn/read-string to parse it, should work fine I guess

Andrew Byala 2022-12-13T07:40:01.805069Z

Posting out here to see if someone with clojure-core-match skills can answer a specific question on my solution to day 13.

Ellis 2022-12-13T09:12:47.073929Z

I started on the same approach! I just went with condp in the end which does the same thing in this trivial case

tschady 2022-12-13T12:37:38.517499Z

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.

Andrew Byala 2022-12-13T15:44:22.532369Z

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)))))

schadocalex 2022-12-13T16:50:22.178429Z

why not use guards for types?

Andrew Byala 2022-12-13T17:14:28.205839Z

@schad.alexis - 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)))))

schadocalex 2022-12-13T17:31:13.182099Z

It's not that ugly for me, at least you know what's going on

👍 1
Andrew Byala 2022-12-13T07:42:05.465939Z

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?