Fork me on GitHub
#adventofcode
<
2020-12-16
>
st3fan02:12:18

I got Day 15 Part 2 down to 450ms

st3fan02:12:54

Rewrote it in C 😉

st3fan02:12:08

Will do a similar solution in Clojure though

misha09:12:49

chief loop officer

😃 2
misha09:12:09

(let [[rules mine other] (parse i)
      valid?     (->> rules vals (reduce into #{}))
      valid      (->> other
                   (remove #(seq (remove valid? %)))
                   (map vec))
      transposed (apply map vector valid)
      candidates (fn [pred]
                   (->> transposed
                     (map-indexed
                       (fn [idx col]
                         (when (every? pred col)
                           idx)))
                     (remove nil?)))
      labels     (loop [done {}
                        todo (->> rules
                               (map-vals candidates)
                               (sort-by #(-> % val count) <)
                               (into PersistentQueue/EMPTY))]
                   (if (empty? todo)
                     done
                     (let [[label cols] (peek todo)
                           todo (pop todo)
                           cols (remove done cols)]
                       (if (-> cols count (= 1))
                         (recur (assoc done (first cols) label) todo)
                         (recur done (conj todo [label cols]))))))]
  (->> labels
    (filter #(-> % val (str/starts-with? "departure")))
    (map key)
    (map mine)
    (reduce *)))

👍 1
misha09:12:11

ofc it would loop forever, if at some point every unmapped label had more than 1 candidate idx. that'd be job for core.logic

2
erwinrooijakkers18:12:31

did not think about core.logic but this is core.logic

mdallastella14:12:46

Namaste. I have a "philosophical" question about the first problem of day 1. I saw solutions like this around the internet:

(for [x input y input :when (= 2020 (+ x y))]
  (* x y))

mdallastella14:12:08

but what if my input list is (1010 )? Isn't going to stop on the first element?

andrea.crotti14:12:51

That's probably true

andrea.crotti14:12:04

Another check to make sure the numbers are not the same is enough

andrea.crotti14:12:08

But apparently it wasn't necessary given the input data

mdallastella14:12:17

I agree, but given the statement: > Specifically, they need you to find the two entries that sum to `2020` and then multiply those two numbers together.

mdallastella14:12:35

They won't be two entries, but one

mdallastella14:12:21

Anyway checking that are different can be enough

mdallastella14:12:25

but if I have, let's say (1010 ) the elements are two

mdallastella14:12:25

Maybe I'm a little pedantic...

andrea.crotti14:12:50

hehe well I think noone cares about the perfect solution as long as it works and it's fast enough 😄

😅 1
👍 1
misha14:12:52

you can compare indexes instead of actual numbers in case you want to be pedantic

(let [input [1010 1721 299 1465]]
  (for [[a x] (map-indexed vector input)
        [b y] (map-indexed vector input)
        :when (= 2020 (+ x y))
        :when (not= a b)]
    (* x y)))
=> (514579 514579)

1
misha15:12:53

but then :when (< a b) is even better

alekszelark18:12:20

@vincent.cantin I see you’re back in the game, that’s great!

bubblebobble 2
3