Fork me on GitHub
#adventofcode
<
2023-12-02
>
Chase01:12:31

One of my usual AOC habits is to explore transducers after I get my quick and dirty answer out there. I'm curious why my regular version is the same speed (if not slightly faster) when benchmarking with criterium than the transducer version. I usually find quite the opposite.

Chase01:12:41

relevant code for Part 1:

(defn part-1 [data]
  (->> data
       (map #(re-seq #"\d" %))
       (map (juxt first last))
       (map (comp parse-long (partial apply str)))
       (reduce +)))

(defn part-1-transduce [data]
  (let [xform (comp
                (map #(re-seq #"\d" %))
                (map (juxt first last))
                (map (comp parse-long (partial apply str))))]
    (transduce xform + data)))

borkdude13:12:46

It probably depends on the size of the data

AC05:12:40

solving day 2 just reminds me how much I love programming in clojure.

norman05:12:00

Day 02 - Solutions

wevrem06:12:47

Happily, my approach for part 1 dovetailed nicely with part 2, didn’t have to re-write anything, and that rarely happens for me with AoC.

Sam Ferrell07:12:24

> merge-with max came in quite handy. this is great, did not know about this! +1

Casey07:12:13

yea, same, i happened to set myself up very nicely for part 2 during part 1. https://github.com/Ramblurr/advent-of-code/blob/main/src/aoc/2023/day02.clj

Ryan Martin07:12:35

probably influenced by day 1, but I keep coming back to regex for my solutions: https://github.com/rmrt1n/advent-of-code-2023-clj/blob/main/src/aoc/day02.clj

karlis07:12:44

Had to rewrite parsing logic when part 2 was unveiled, but overall happy how easy today turned out to be https://github.com/skazhy/advent/blob/master/src/advent/2023/day2.clj

Piotr Kaznowski09:12:34

Somehow sorted-map becomes the main data structure so far... https://github.com/caseneuve/aoc2023/blob/master/day02/solution.clj

🆒 1
borkdude11:12:15

Bangs head on keyboard, after a non-optimal night of sleep. The test input works for me, but the "production" input gives a too low number

borkdude11:12:30

https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa7da6236e9670681a93761b81fd66ad26c119164%2Faoc_ui.cljs&amp;repl=true&amp;src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgooZGVmbiBwYXJzZS1saW5lIFtsaW5lXQogIChsZXQgW1tpZCBnYW1lXSAoc3RyL3NwbGl0IGxpbmUgIjogIikKICAgICAgICBpZCAoLT4gKHN0ci9yZXBsYWNlIGlkICJHYW1lICIgIiIpCiAgICAgICAgICAgICBwYXJzZS1sb25nKV0KICAgIHs6aWQgaWQKICAgICA6Z2FtZSAoLT4KICAgICAgICAgICAgIGdhbWUKICAgICAgICAgICAgIChzdHIvc3BsaXQgIjsgIikKICAgICAgICAgICAgICgtPj4gKG1hcCAoZm4gW2VdCiAgICAgICAgICAgICAgICAgICAgICAgICAoLT4gKG1hcHYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMoLT4gKHJldmVyc2UgKHN0ci9zcGxpdCAlICIgIikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1cGRhdGUgMSBwYXJzZS1sb25nKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdHIvc3BsaXQgZSAiLCAiKSkpKSkKICAgICAgICAgICAgICAgKG1hcHYgIyhpbnRvIHt9ICUpKSkpfSkpCgooY29tbWVudAogIChwYXJzZS1saW5lICJHYW1lIDE6IDMgYmx1ZSwgNCByZWQ7IDIgZ3JlZW4iKQogICkKCihkZWYgZXhhbXBsZSAiR2FtZSAxOiAzIGJsdWUsIDQgcmVkOyAxIHJlZCwgMiBncmVlbiwgNiBibHVlOyAyIGdyZWVuCkdhbWUgMjogMSBibHVlLCAyIGdyZWVuOyAzIGdyZWVuLCA0IGJsdWUsIDEgcmVkOyAxIGdyZWVuLCAxIGJsdWUKR2FtZSAzOiA4IGdyZWVuLCA2IGJsdWUsIDIwIHJlZDsgNSBibHVlLCA0IHJlZCwgMTMgZ3JlZW47IDUgZ3JlZW4sIDEgcmVkCkdhbWUgNDogMSBncmVlbiwgMyByZWQsIDYgYmx1ZTsgMyBncmVlbiwgNiByZWQ7IDMgZ3JlZW4sIDE1IGJsdWUsIDE0IHJlZApHYW1lIDU6IDYgcmVkLCAxIGJsdWUsIDMgZ3JlZW47IDIgYmx1ZSwgMSByZWQsIDIgZ3JlZW4iKQoKKGRlZiBpbnB1dCAoLT4%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAyKSkKICAgICAgICAgICAgICNfc3B5CiAgICAgICAgICAgICBzdHIvdHJpbQogICAgICAgICAgICAgc3RyL3NwbGl0LWxpbmVzCiAgICAgICAgICAgICAobWFwdiBwYXJzZS1saW5lKSkpCgooY29tbWVudAogIChzcHkgaW5wdXQpKQoKKGRlZm4gbXktcGx1cyBbJiB4c10KICAoYXBwbHkgKyAobWFwIChmbmlsIGlkZW50aXR5IDApIHhzKSkpCgooY29tbWVudAogIChteS1wbHVzIDEganMvdW5kZWZpbmVkIDIganMvdW5kZWZpbmVkKSkKCihkZWZuIHN1bS1nYW1lIFtnYW1lXQogIChhcHBseSBtYXB2IG15LXBsdXMKICAgIChtYXB2IChqdXh0IDpyZWQgOmdyZWVuIDpibHVlKSBnYW1lKSkpCgooY29tbWVudAogIChzdW0tZ2FtZSBbezpyZWQgMSA6Ymx1ZSAyIDpncmVlbiAzfQogICAgICAgICAgICAgezpyZWQgNSA6Ymx1ZSAxMzM3fV0pKQoKKGRlZm4gcGFydC0xCiAgW10KICAoLT4%2BIGlucHV0CiAgICAoZmlsdGVydiAjKGxldCBbZ2FtZSAoOmdhbWUgJSkKICAgICAgICAgICAgICAgICAgICBbciBnIGJdIChzdW0tZ2FtZSBnYW1lKV0KICAgICAgICAgICAgICAgIChhbmQKICAgICAgICAgICAgICAgICAgKDw9IHIgMTIpCiAgICAgICAgICAgICAgICAgICg8PSBnIDEzKQogICAgICAgICAgICAgICAgICAoPD0gYiAxNCkpKSkKICAgIChtYXB2IDppZCkKICAgIChhcHBseSArKSkpCgooY29tbWVudAogIChwYXJ0LTEpKQ%3D%3D - any hints welcome, I'm going off for lunch ;)

😍 2
borkdude11:12:11

I think I got it, I misinterpreted the puzzle, I summed all the red, green, blue and then compared to the max

borkdude11:12:57

That's it, part 1 fixed

Ryan Martin11:12:02

I had the same mistake, summed the colors instead of using max

oyakushev11:12:06

@UTFAPNRPT Love how terse your implementation is! The parsing part certainly took me a while to understand. Also, power could just be #(apply * (vals %)) . Ah, I see that it couldn't, since you keep game id as one of the keys.

borkdude11:12:14

I thought I made a mistake earlier by using array indexes as the game id but then I thought: perhaps they use sparse ids, but this wasn't the case in my input

tschady12:12:23

• Sometimes I find spelling out the parser easier to read, though I’m not completely happy with mine it was fast. • using [r g b] tuples in a matrix lets you do things like map >= to check size and makes power just the max of the transpose. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2023/d02.clj

borkdude12:12:39

https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa7da6236e9670681a93761b81fd66ad26c119164%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgooZGVmIGlucHV0ICgtPiAoanMtYXdhaXQgKGZldGNoLWlucHV0IDIwMjMgMikpCiAgICAgICAgICAgICBzdHIvdHJpbQogICAgICAgICAgICAgc3RyL3NwbGl0LWxpbmVzKSkKCihkZWZuIGdhbWVzIFtzXQogICgtPj4gKC0%2BIHMgKHN0ci9zcGxpdCAjIjoiKSBzZWNvbmQKICAgICAgICAgKHN0ci9yZXBsYWNlICMiKFxkKykgKFx3KykiICJ7XCIkMlwiOiAkMX0iKQogICAgICAgICAoc3RyL3NwbGl0ICMiWyw7XSIpKQogICAgKG1hcCBqcy9KU09OLnBhcnNlKQogICAgKGFwcGx5IG1lcmdlLXdpdGggbWF4KQogICAgKChqdXh0IDpyZWQgOmdyZWVuIDpibHVlKSkpKQoKKGNvbW1lbnQKICAoZ2FtZXMgKGZpcnN0IGlucHV0KSkpCgooZGVmIHAxCiAgKGxldCBbcnVsZXMgKHZhbHMgeyJyZWQiIDEyICJncmVlbiIgMTMgImJsdWUiIDE0fSkKICAgICAgICBwb3NzaWJsZT8gIyhldmVyeT8gdHJ1ZT8gKG1hcCAoZm4gW2EgYl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8PSBhIGIpKSAlIHJ1bGVzKSldCiAgICAocGFydGlhbCBrZWVwLWluZGV4ZWQKICAgICAgKGZuIFtpZCBnYW1lXSAod2hlbiAocG9zc2libGU%2FIGdhbWUpIChpbmMgaWQpKSkpKSkKCihkZWYgcDIgKHBhcnRpYWwgbWFwICMocmVkdWNlIChmbiBbYSBiXSAoKiBhIGIpKSAlKSkpCgooZGVmbiBzb2x2ZSBbaW5wdXRdCiAgKGxldCBbc29sdmUtd2l0aCAjKC0%2BPiBpbnB1dCAobWFwIGdhbWVzKSAlIChhcHBseSArKSldCiAgICB7OnBhcnQxIChzb2x2ZS13aXRoIHAxKSA6cGFydDIgKHNvbHZlLXdpdGggcDIpfSkpCgooY29tbWVudAogIChzb2x2ZSBpbnB1dCkpCgooY29tbWVudAogIChkZWYgdGVzdC1pbnB1dCAiR2FtZSAxOiAzIGJsdWUsIDQgcmVkOyAxIHJlZCwgMiBncmVlbiwgNiBibHVlOyAyIGdyZWVuCkdhbWUgMjogMSBibHVlLCAyIGdyZWVuOyAzIGdyZWVuLCA0IGJsdWUsIDEgcmVkOyAxIGdyZWVuLCAxIGJsdWUKR2FtZSAzOiA4IGdyZWVuLCA2IGJsdWUsIDIwIHJlZDsgNSBibHVlLCA0IHJlZCwgMTMgZ3JlZW47IDUgZ3JlZW4sIDEgcmVkCkdhbWUgNDogMSBncmVlbiwgMyByZWQsIDYgYmx1ZTsgMyBncmVlbiwgNiByZWQ7IDMgZ3JlZW4sIDE1IGJsdWUsIDE0IHJlZApHYW1lIDU6IDYgcmVkLCAxIGJsdWUsIDMgZ3JlZW47IDIgYmx1ZSwgMSByZWQsIDIgZ3JlZW4iKQogIChkZWYgc29sdmUtd2l0aCAjKC0%2BPiB0ZXN0LWlucHV0CiAgICAgICAgICAgICAgICAgICAgIHN0ci9zcGxpdC1saW5lcwogICAgICAgICAgICAgICAgICAgICAobWFwIGdhbWVzKSAlCiAgICAgICAgICAgICAgICAgICAgIChhcHBseSArKSkpCiAgCiAgKD0gOCAoc29sdmUtd2l0aCBwMSkpCiAgKD0gMjI4NiAoc29sdmUtd2l0aCBwMikpCiAgKQ%3D%3D The above is @UUAKPEMJ9’s solution. I used JSON/parse instead of read-string and there were some issues around * and <= not being available as reified functions (https://github.com/squint-cljs/squint/issues/400)

🙌 1
Luke Zeitlin13:12:27

(require '[clojure.string :as str])

(defn parse-count [s]
  (let [[cnt color] (str/split s #" ")]
    [(keyword color) (parse-long cnt)]))

(defn parse-hand [s]
  (->> (str/split s #", ")
       (map parse-count)
       (into {})))

(defn game-maxes [s]
  (let [[game-name-str counts-str] (str/split s #": ")
        max-counts (-> counts-str
                       (str/split #"; ")
                       (->> (map parse-hand)
                            (apply merge-with max)))
        game-id (-> game-name-str (str/split #" ")
                    second
                    parse-long)]
    [game-id max-counts]))

(def thresholds {:red 12 :green 13 :blue 14})

(defn game-within-threshold? [[_game-id maxes]]
  (->> (merge-with >= thresholds maxes)
       vals
       (every? true?)))

(defn power-val [[_game-id maxes]]
  (->> maxes
       vals
       (reduce *)))

(def part1-result
  (-> (slurp "aoc/input2.txt")
      (str/split #"\n")
      (->> (map game-maxes)
           (filter game-within-threshold?)
           (map first)
           (reduce +))))

(def part2-result
  (-> (slurp "aoc/input2.txt")
      (str/split #"\n")
      (->> (map game-maxes)
           (map power-val)
           (reduce +))))

CarnunMP13:12:24

less to get snagged on than with Day 1 🙂

(defn possible? [game]
  (let [c->max {"red" 12, "green" 13, "blue" 14}]
    ;; for every selection in this game...
    (every? #(every? (fn [c] ; ... every color <= max (or absent)
                       (<= (get % c 0) (get c->max c)))
                     (keys c->max))
            (:cubes game))))


;; part 2
(defn min-cubes [game]
  ;; reduce over all 'cubes' (selections of cubes) in this game...
  (reduce (fn [m cube]
            (->> m
                 ;; ... to produce a map of min required for each color
                 (map (fn [[c n]] [c (max n (get cube c 0))]))
                 (into {})))
          {"red" 0
           "green" 0
           "blue" 0}
          (:cubes game)))


(defn solve [input & {:keys [part]}]
  (->> (parse input)
       (keep (fn [game]
               (case part
                 1 (when (possible? game)
                     (:id game))
                 2 (->> (min-cubes game)
                        (vals)
                        (apply *)))))
       (apply +)))
https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2023/d2.clj (if this trend continues...??)

borkdude13:12:07

@UE7LPTG1L https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa7da6236e9670681a93761b81fd66ad26c119164%2Faoc_ui.cljs&amp;repl=true&amp;src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgoocmVxdWlyZSAnW2Nsb2p1cmUuc3RyaW5nIDphcyBzdHJdKQoKKGRlZm4gcGFyc2UtY291bnQgW3NdCiAgKGxldCBbW2NudCBjb2xvcl0gKHN0ci9zcGxpdCBzICMiICIpXQogICAgWygjPyg6c3F1aW50IGlkZW50aXR5IDpkZWZhdWx0IGtleXdvcmQpIGNvbG9yKSAocGFyc2UtbG9uZyBjbnQpXSkpCgooY29tbWVudAogIChwYXJzZS1jb3VudCAiMSBncmVlbiIpKQoKKGRlZm4gcGFyc2UtaGFuZCBbc10KICAoLT4%2BIChzdHIvc3BsaXQgcyAjIiwgIikKICAgIChtYXAgcGFyc2UtY291bnQpCiAgICAoaW50byB7fSkpKQoKKGNvbW1lbnQKICAocGFyc2UtaGFuZCAiMSBncmVlbiwgMiBibHVlIikpCgooZGVmbiBnYW1lLW1heGVzIFtzXQogIChsZXQgW1tnYW1lLW5hbWUtc3RyIGNvdW50cy1zdHJdIChzdHIvc3BsaXQgcyAjIjogIikKICAgICAgICBtYXgtY291bnRzICgtPiBjb3VudHMtc3RyCiAgICAgICAgICAgICAgICAgICAgIChzdHIvc3BsaXQgIyI7ICIpCiAgICAgICAgICAgICAgICAgICAgICgtPj4gKG1hcCBwYXJzZS1oYW5kKQogICAgICAgICAgICAgICAgICAgICAgIChhcHBseSBtZXJnZS13aXRoIG1heCkpKQogICAgICAgIGdhbWUtaWQgKC0%2BIGdhbWUtbmFtZS1zdHIgKHN0ci9zcGxpdCAjIiAiKQogICAgICAgICAgICAgICAgICBzZWNvbmQKICAgICAgICAgICAgICAgICAgcGFyc2UtbG9uZyldCiAgICBbZ2FtZS1pZCBtYXgtY291bnRzXSkpCgooY29tbWVudAogIChnYW1lLW1heGVzICJHYW1lIDE6IDEgZ3JlZW4sIDIgYmx1ZTsgMiBncmVlbiwgMSByZWQiKSkKCihkZWYgdGhyZXNob2xkcyB7OnJlZCAxMiA6Z3JlZW4gMTMgOmJsdWUgMTR9KQoKKGRlZm4gZ2FtZS13aXRoaW4tdGhyZXNob2xkPyBbW19nYW1lLWlkIG1heGVzXV0KICAoLT4%2BIChtZXJnZS13aXRoICMoPj0gJTEgJTIpIHRocmVzaG9sZHMgbWF4ZXMpCiAgICB2YWxzCiAgICAoZXZlcnk%2FIHRydWU%2FKSkpCgooY29tbWVudAogIChnYW1lLXdpdGhpbi10aHJlc2hvbGQ%2FIChnYW1lLW1heGVzICJHYW1lIDE6IDEgZ3JlZW4sIDIgYmx1ZTsgMiBncmVlbiwgMSByZWQiKSkKICApCgooZGVmbiBwb3dlci12YWwgW1tfZ2FtZS1pZCBtYXhlc11dCiAgKC0%2BPiBtYXhlcwogICAgdmFscwogICAgKHJlZHVjZSAjKCogJTEgJTIpKSkpCgooY29tbWVudAogIChwb3dlci12YWwgKGdhbWUtbWF4ZXMgIkdhbWUgMTogMSBncmVlbiwgMiBibHVlOyAyIGdyZWVuLCAxIHJlZCIpKQogICkKCihkZWYgcGFydDEtcmVzdWx0CiAgKC0%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAyKSkKICAgIHN0ci90cmltCiAgICAoc3RyL3NwbGl0ICMiXG4iKQogICAgKC0%2BPiAobWFwdiBnYW1lLW1heGVzKQogICAgICAoZmlsdGVyIGdhbWUtd2l0aGluLXRocmVzaG9sZD8pCiAgICAgIChtYXAgZmlyc3QpCiAgICAgIChyZWR1Y2UgKykpKSkKCihkZWYgcGFydDItcmVzdWx0CiAgKC0%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAyKSkKICAgIHN0ci90cmltCiAgICAoc3RyL3NwbGl0ICMiXG4iKQogICAgKC0%2BPiAobWFwIGdhbWUtbWF4ZXMpCiAgICAgIChtYXAgcG93ZXItdmFsKQogICAgICAocmVkdWNlICspKSkp

🙌 1
borkdude13:12:44

I needed to insert str/trim to get rid of the newline in the input, I wonder why that wasn't a problem in your case

borkdude13:12:30

ah because it's a difference in squint: user=> (str/split "foo\nbar\n" #"\n") ;;=> [ 'foo', 'bar', '' ] facepalm

Felipe14:12:01

@UUAKPEMJ9 good idea using sorted-map

borkdude14:12:02

Fixed issues in squint, * and >= etc can now be used as higher order functions and str/split elides empty splitted elements (when limit = nil), like in CLJS Again @UE7LPTG1L’s https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa7da6236e9670681a93761b81fd66ad26c119164%2Faoc_ui.cljs&amp;repl=true&amp;src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgoocmVxdWlyZSAnW2Nsb2p1cmUuc3RyaW5nIDphcyBzdHJdKQoKKGRlZm4gcGFyc2UtY291bnQgW3NdCiAgKGxldCBbW2NudCBjb2xvcl0gKHN0ci9zcGxpdCBzICMiICIpXQogICAgWygjPyg6c3F1aW50IGlkZW50aXR5IDpkZWZhdWx0IGtleXdvcmQpIGNvbG9yKSAocGFyc2UtbG9uZyBjbnQpXSkpCgooY29tbWVudAogIChwYXJzZS1jb3VudCAiMSBncmVlbiIpKQoKKGRlZm4gcGFyc2UtaGFuZCBbc10KICAoLT4%2BIChzdHIvc3BsaXQgcyAjIiwgIikKICAgIChtYXAgcGFyc2UtY291bnQpCiAgICAoaW50byB7fSkpKQoKKGNvbW1lbnQKICAocGFyc2UtaGFuZCAiMSBncmVlbiwgMiBibHVlIikpCgooZGVmbiBnYW1lLW1heGVzIFtzXQogIChsZXQgW1tnYW1lLW5hbWUtc3RyIGNvdW50cy1zdHJdIChzdHIvc3BsaXQgcyAjIjogIikKICAgICAgICBtYXgtY291bnRzICgtPiBjb3VudHMtc3RyCiAgICAgICAgICAgICAgICAgICAgIChzdHIvc3BsaXQgIyI7ICIpCiAgICAgICAgICAgICAgICAgICAgICgtPj4gKG1hcCBwYXJzZS1oYW5kKQogICAgICAgICAgICAgICAgICAgICAgIChhcHBseSBtZXJnZS13aXRoIG1heCkpKQogICAgICAgIGdhbWUtaWQgKC0%2BIGdhbWUtbmFtZS1zdHIgKHN0ci9zcGxpdCAjIiAiKQogICAgICAgICAgICAgICAgICBzZWNvbmQKICAgICAgICAgICAgICAgICAgcGFyc2UtbG9uZyldCiAgICBbZ2FtZS1pZCBtYXgtY291bnRzXSkpCgooY29tbWVudAogIChnYW1lLW1heGVzICJHYW1lIDE6IDEgZ3JlZW4sIDIgYmx1ZTsgMiBncmVlbiwgMSByZWQiKSkKCihkZWYgdGhyZXNob2xkcyB7OnJlZCAxMiA6Z3JlZW4gMTMgOmJsdWUgMTR9KQoKKGRlZm4gZ2FtZS13aXRoaW4tdGhyZXNob2xkPyBbW19nYW1lLWlkIG1heGVzXV0KICAoLT4%2BIChtZXJnZS13aXRoID49IHRocmVzaG9sZHMgbWF4ZXMpCiAgICB2YWxzCiAgICAoZXZlcnk%2FIHRydWU%2FKSkpCgooY29tbWVudAogIChnYW1lLXdpdGhpbi10aHJlc2hvbGQ%2FIChnYW1lLW1heGVzICJHYW1lIDE6IDEgZ3JlZW4sIDIgYmx1ZTsgMiBncmVlbiwgMSByZWQiKSkKICApCgooZGVmbiBwb3dlci12YWwgW1tfZ2FtZS1pZCBtYXhlc11dCiAgKC0%2BPiBtYXhlcwogICAgdmFscwogICAgKHJlZHVjZSAqKSkpCgooY29tbWVudAogIChwb3dlci12YWwgKGdhbWUtbWF4ZXMgIkdhbWUgMTogMSBncmVlbiwgMiBibHVlOyAyIGdyZWVuLCAxIHJlZCIpKQogICkKCihkZWYgcGFydDEtcmVzdWx0CiAgKC0%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyMyAyKSkKICAgIChzdHIvc3BsaXQgIyJcbiIpCiAgICAoLT4%2BIChtYXB2IGdhbWUtbWF4ZXMpCiAgICAgIChmaWx0ZXIgZ2FtZS13aXRoaW4tdGhyZXNob2xkPykKICAgICAgKG1hcCBmaXJzdCkKICAgICAgKHJlZHVjZSArKSkpKQoKKGRlZiBwYXJ0Mi1yZXN1bHQKICAoLT4gKGpzLWF3YWl0IChmZXRjaC1pbnB1dCAyMDIzIDIpKQogICAgKHN0ci9zcGxpdCAjIlxuIikKICAgICgtPj4gKG1hcCBnYW1lLW1heGVzKQogICAgICAobWFwIHBvd2VyLXZhbCkKICAgICAgKHJlZHVjZSArKSkpKQ%3D%3D but essentially the same now except reading the input of course

Luke Zeitlin14:12:57

Nice to put runnable comments for the intermediary steps like this

potetm15:12:00

lol I'm glad ya'll figured out the summing/maxing thing. I was pretty sure I was misinterpreting, but I wasn't' at all sure how.

potetm15:12:41

Fortunately clojure is amazing. (apply merge-with + coll) became (apply merge-with max picks)

potetm15:12:46

re having to rewrite parsing: I've found that lossless parsing really pays off in AoC (and in every day programming as well!)

wevrem15:12:43

What do you mean, @U07S8JGF7, by lossless parsing?

potetm15:12:27

"don't throw away any information"

wevrem15:12:50

And where did you end up using merge-with +?

potetm15:12:15

so, e.g. instead of grabbing the min values from each line, have a parsing phase that grabs all the values

potetm15:12:26

merge-with + was a mistake.

potetm15:12:44

It became merge-with max

👍 1
wevrem15:12:54

I took a gamble and did not do lossless parsing. I think I picked up that trick from @U067R559Q a couple years ago. It paid off this time. I did not keep track of individual sets within each game (which is more effort because the number of sets per game is not fixed), ignored commas and semicolons and just reduced with max. I guess it was lucky that approach worked for both part 1 and part 2. (I had guessed that part 2 would involve some change to the limits, so when it was revealed it was too easy.)

Piotr Kaznowski15:12:20

@UA2U3KW0L yeah, I refactored when the 2nd part was revealed, as it became obvious that only edge cases are important and colors are only needed as "indexes" for unifying data as no further look-ups will follow; then I refactored a bit further, so the solution algorithms accept only vals, not maps.

wevrem16:12:44

I love this ascii art trebuchet.

----@
* ! /^\

Chase17:12:20

https://github.com/chase-lambert/aoc-clojure/blob/main/src/aoc/2023/day_02.clj Another hacky one for me, I'm excited to check out these more elegant solutions from you folks now

Chase17:12:36

folks seem reluctant to tackle part 2 so far but I didn't find it that much more difficult than part 1. Could just be early though

Chase18:12:19

oh man, some of the solutions are so sweet! I feel like my imposter syndrome needs a disclaimer if you spent a good amount of time refactoring to look so nice before posting or is this just naturally how you code off the bat

Luke Zeitlin18:12:24

I would love and "honour-mode" where you get to submit only one solution without running it and you get the star if it passes first time. No repl cheating

potetm18:12:57

I'd be 0/2 this year. :coneofshame:

potetm18:12:22

That said, I don't redo anything. I finish and insta commit.

muthui shere18:12:39

Day 2 seems to be very easy compare to Day 1 (especially part 2). Did a Live Coding used Hyperfiddle for TDD and its available on https://www.youtube.com/watch?v=aF4OfRGnobk . https://github.com/muthuishere/advent-of-code-clojure-2023/blob/main/src/day2.clj

dpsutton18:12:44

Do you mind deleting this comment? By all means send your live coding to the main channel but don’t put solutions into the channel

dpsutton18:12:56

And use a snippet for such a long code block

1
Jakob Durstberger18:12:45

I enjoyed day 2. Just parsing colour and count in part 1 turned out to be helpful for the second part. Though reading this thread it would have been nice to know about merge-with https://github.com/JDurstberger/aoc-2023-clj/tree/main/src/day_2 Here is today's video https://youtu.be/Whff9f_BrL8

dpsutton18:12:53

(And could you please delete the link preview as well? It’s an awesome share just don’t want spoilers leaking out) edit: link previews are fine here in the thread, just don’t want code solutions in the main channel for people who are still solving them)

Cora (she/her)02:12:16

my day 2 in squint -- didn't use the playground this time due to time constraints (I ended up spending more time working on the playground than doing the actual problems): https://gist.github.com/corasaurus-hex/e800b30d092db6efaaa182aa51d57431

🎉 1
pez13:12:30

Decided to go for TDD, because parsing input always gets trickier than I think it will. 😃

V21:12:54

(ns day02
  (:require [ :as io]
            [clojure.string :as string]))

(defn parse-subset [subset]
  (let [[[_ r]] (re-seq #"(\d+) red" subset)
        [[_ g]] (re-seq #"(\d+) green" subset)
        [[_ b]] (re-seq #"(\d+) blue" subset)]
    [(or (some-> r parse-long) 0)
     (or (some-> g parse-long) 0)
     (or (some-> b parse-long) 0)]))

(defn parse [line]
  (let [[_ subsets] (string/split line #":")]
    (->>  (string/split subsets #";")
          (map parse-subset))))

(defn part01 [lines]
  (->> lines
       (map parse)
       (map-indexed
        (fn [idx subsets]
          [(+ idx 1)
           (->> subsets
                (map (fn [[r g b]] (and (<= r 12) (<= g 13) (<= b 14))))
                (flatten)
                (every? identity))]))
       (filter (fn [[_ p]] p))
       (map first)
       (reduce +)))

(defn part02 [lines]
  (->> lines
       (map parse)
       (map
        (fn [subsets]
          (->> subsets
               (reduce (fn [[ar ag ab] [r g b]]
                         [(max ar r) (max ag g) (max ab b)])
                       [0 0 0])
               (reduce *))))
       (reduce +)))

(comment
  (with-open [r (io/reader "day02.txt")]
    (part01 (line-seq r)))
  (with-open [r (io/reader "day02.txt")]
    (part02 (line-seq r))))

Luke Zeitlin16:12:18

Wanted to make a poll asking people about their approach to AoC questions. Is this not possible in slack without a plugin?

dpsutton16:12:13

I guess not. I often do things like: How do you do X? • 1️⃣ foo • 2️⃣ bar • 3️⃣ baz and get people to use the emoji reactions 1️⃣ , 2️⃣ , or 3️⃣ and discuss in a thread

1
🙏 1
Luke Zeitlin16:12:41

Ah yeah that works

Luke Zeitlin16:12:48

How do you think about performance in your AoC solutions: 1️⃣ Not at all 2️⃣ It's lower priority than some other style / readability considerations 3️⃣ It's an important aspect of my solution - I optimize it intuitively 4️⃣ It's an important aspect of my solution - I measure it 5️⃣ Something else

1️⃣ 6
2️⃣ 14
5️⃣ 2
4️⃣ 1
elken16:12:20

As long as it runs in tens of seconds at most, I'm happy 😄 Since I compile my clerk notebooks, the solutions run every time I deploy so I need them fast but I'm not too fussed about shaving milliseconds

wevrem16:12:08

I’m № 1 all the time… until you get to that day where it takes 10 million years to solve.

2
Luke Zeitlin17:12:12

I favour readability over performance for this kind of thing, although I guess readability is a bit subjective

💯 1
Alvydas Vitkauskas17:12:47

I did AoC in Clojure last year, and I found that it’s quite easy (for a novice at least) to write correct and (I think) idiomatic Clojure code that runs quite slow. Then you have to think about lazy vs. not-lazy sequences, reflection, boxing etc. I was especially surprised that not-lazy code can be quicker that lazy (as laziness is mostly explained as a mean to save resources and not perform calculations until they are really needed).

👍 1
potetm17:12:35

It depends a little on what you're trying to do. Given that I'm only trying to solve the problems, I only care about perf when it matters, and I care about "readability" not a wit 😄

potetm17:12:20

fwiw I find "readability" to be a grandly misunderstood topic in software, so I'm probably not representative

Cora (she/her)17:12:49

I do AoC for fun, so I only think of perf when it's fun to or if the solution space my code searches is too large for more naive/fun solutions

1
Cora (she/her)17:12:20

this is also probably why I burn out on AoC every year when it hits double digits -- it typically becomes more of a slog at that point and less fun -- I already have a job that challenges me in that way and so my recreation doesn't have to

Chase17:12:28

I do like to go back and check performance after solving it in my normal hacked up way. I get a little sad when I see my also hacked up Rust code solves it 10x faster with the same lack of initial care. I guess it doesn't mean anything but I wish we could just magically have Clojure be super fast lol (clojure is still 10x more fun to write though of course)

🙌 1
potetm17:12:31

@U9J50BY4C I'm curious to see some side-by-sides. People keep saying rust is great, but my initial take is that it's monstrously complex and forces you to deal with computer tedium. I'd be curious if you came up with relatively straightforward solutions.

Chase17:12:06

Yeah, for example my first few days of 2015 were written how I normally would do Clojure and Rust I guess. When benchmarking them I see that huge performance gain with Rust. I should probably switch the apply to reduce and whatnot. Caveat: my idiomatic code back in 2015 might just suck in general but that's just when I tried some benchmarking recently https://github.com/chase-lambert/aoc-clojure/tree/main/src/aoc/2015 https://github.com/chase-lambert/aoc_rust/tree/main/aoc_2015/src

potetm17:12:25

This is a great resource! Thank you!

Chase17:12:47

I'm using this aoc tool called cargo-aoc though because it does the benchmarking for me but it shouldn't make much of a difference I think

Cora (she/her)17:12:00

Isn't the big trick to making rust easy just doing copy all the time instead of dealing with ownership?

Cora (she/her)17:12:07

I feel like someone told me that

pez17:12:53

I care of the performance when it seems like I’d learn something from it.

potetm18:12:14

gah every other language is so clunky after doing clojure for 10 years. I know part of it is just that clojure is near at hand for me, but emotionally it's like watching kids derp around taking 10x the effort for simple tasks.

potetm18:12:04

I mean that in as non-judgemental a way as possible. It's just my emotional (uninformed) reaction.

potetm18:12:32

(Your code is very good btw. Wasn't a comment on that. I can understand it easily. It's the lang, not the writer.)

Chase18:12:26

Rust definitely gets wild. I find it surprisingly straightforward (once you grok the borrow checker) for regular stuff especially considering how performant it is. It has some nice "high level" features. But when you start really getting into harder tasks, things get crazy quick and I run back to sweet, sweet Clojure.

Luke Zeitlin18:12:56

Did some cryptography puzzles from https://cryptopals.com/ in Rust and found it less painful than i was expecting although I'm pretty sure i was cutting corners in a way that would be considered sloppy by proper rusties

Luke Zeitlin18:12:33

.unwrap() all over the place - tis the season 🎅

😂 1
muthui shere18:12:39
replied to a thread:Day 02 - Solutions

Day 2 seems to be very easy compare to Day 1 (especially part 2). Did a Live Coding used Hyperfiddle for TDD and its available on https://www.youtube.com/watch?v=aF4OfRGnobk . https://github.com/muthuishere/advent-of-code-clojure-2023/blob/main/src/day2.clj

Cora (she/her)19:12:06

is the site down for anyone else?

Cora (she/her)19:12:14

oh, no, it works now