adventofcode

misha 2020-12-16T09:21:49.313Z

chief loop officer

πŸ˜ƒ 2
misha 2020-12-16T09:26:09.313100Z

(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
misha 2020-12-16T09:38:11.314500Z

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
erwinrooijakkers 2020-12-16T18:14:22.329200Z

ah indeed

erwinrooijakkers 2020-12-16T18:14:24.329400Z

smart

erwinrooijakkers 2020-12-16T18:14:31.329600Z

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

mdallastella 2020-12-16T14:22:01.317500Z

@mdallastella has joined the channel

mdallastella 2020-12-16T14:25:46.319300Z

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

mdallastella 2020-12-16T14:27:08.320600Z

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

2020-12-16T14:27:51.320700Z

That's probably true

2020-12-16T14:28:04.320900Z

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

2020-12-16T14:29:08.321100Z

But apparently it wasn't necessary given the input data

mdallastella 2020-12-16T14:30:17.321300Z

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.

mdallastella 2020-12-16T14:30:35.321500Z

They won't be two entries, but one

mdallastella 2020-12-16T14:31:21.321700Z

Anyway checking that are different can be enough

mdallastella 2020-12-16T14:32:25.321900Z

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

mdallastella 2020-12-16T14:33:25.322100Z

Maybe I'm a little pedantic...

2020-12-16T14:46:50.323Z

hehe well I think noone cares about the perfect solution as long as it works and it's fast enough πŸ˜„

πŸ‘ 1
πŸ˜… 1
misha 2020-12-16T14:52:52.323400Z

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
misha 2020-12-16T15:00:53.324400Z

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

jewiet 2020-12-16T17:03:33.327100Z

@fana has joined the channel

2020-12-16T18:39:24.331500Z

Day 17 answers thread - Post your answers here

peterc 2020-12-17T08:08:17.345200Z

Ooops my mistake, I meant @@zelark :X

πŸ˜… 1
nbardiuk 2020-12-17T08:58:37.346700Z

@zelark I love the frequences approach, it improved my slow implementation from 5s to 450ms

misha 2020-12-17T09:31:09.348Z

9 seconds, and I don't care d

πŸ§˜β€β™‚οΈ 3
nbardiuk 2020-12-17T10:01:22.348300Z

@misha sometimes it is harder to "let it go"

misha 2020-12-17T10:08:15.348500Z

not after ~day15 usually

benoit 2020-12-17T13:35:46.353Z

Representing the pocket dimensions as a set of active cubes. Looks similar to others here. https://github.com/benfle/advent-of-code-2020/blob/main/day17.clj

πŸ‘ 3
benoit 2020-12-17T13:36:43.353400Z

Of course I had to rewrite the function that compute the neighbor coordinates for part2 to support an arbitrary number of dimensions πŸ™‚

2020-12-17T13:40:19.353700Z

https://github.com/benfle/advent-of-code-2020/blob/main/day17.clj#L55-L60 could also be written like (->> (all-neighbor-coordinates state) (filter (partial next-cube-active? state)) set)

2020-12-17T13:47:05.354400Z

There is also the transducer way which should run faster: (into #{} (filter (partial next-cube-active? state)) (all-neighbor-coordinates state))

benoit 2020-12-17T13:47:55.354600Z

Thanks, done.

benoit 2020-12-17T13:49:46.354800Z

That would be cool if my IDE could detect this kind of semantic-preserving transformations and automatically propose them :)

βž• 1
2020-12-17T13:50:34.355Z

Which IDE are you using? Is it open source?

benoit 2020-12-17T14:07:32.355400Z

emacs, I believe it is open source lol

2020-12-17T14:09:58.355600Z

It could eventually be in https://github.com/borkdude/clj-kondo/blob/master/doc/editor-integration.md#emacs

2020-12-17T14:13:28.356200Z

near the goal ... https://github.com/borkdude/clj-kondo/issues/323

benoit 2020-12-17T14:19:48.356600Z

Yeah I would certainly leverage things in clj-kondo πŸ™‚ But I'm not a fan of the overall approach of linters. This should be a la carte and an assistant to help you navigate the design space. Not a collection of rules that you must respect or be warned about.

Joe 2020-12-17T16:03:52.366500Z

https://github.com/RedPenguin101/aoc2020/blob/main/day17.clj - Fun! About 500ms for Part 2

πŸ‘ 3
euccastro 2020-12-18T03:13:06.384500Z

nice! nit: (apply concat (map neighbors coords)) could be just (mapcat neighbors coords)

markw 2020-12-18T04:26:37.386Z

better late than never: https://github.com/Solaxun/aoc2020_clj/blob/main/src/aoc2020_clj/day17.clj

πŸ‘ 1
Aleks 2020-12-17T05:40:48.336100Z

My solution ^_^ https://github.com/zelark/AoC-2020/blob/master/src/zelark/aoc_2020/day_17.clj

πŸ‘ 5
😍 4
☺️ 4
2020-12-17T05:56:25.336500Z

so fast ! I can’t past part 1, I have a bug or a misunderstanding.

2020-12-17T06:02:08.336700Z

I don’t understand how the neighbors are counted, it seems inconsistent with the example .. maybe my english has a problem.

Aleks 2020-12-17T06:09:12.336900Z

I believe your english much better than mine. I often have difficulties to understand what they want in the end.

2020-12-17T06:10:27.337200Z

I don’t understand why at z=-1 in their example, the first cube becomes active. I don’t see 3 active neighbors.

2020-12-17T06:12:24.337400Z

Time to work, will continue tonight.

euccastro 2020-12-17T06:13:55.337600Z

Today I got it cleaner than yesterday, but the solution to the second one takes ~780ms https://github.com/euccastro/advent-of-code-2020/blob/master/src/advent/day17.clj

πŸ‘ 2
euccastro 2020-12-17T06:20:42.338300Z

@zelark really neat!

πŸ™ 1
euccastro 2020-12-17T06:22:44.338600Z

I left the first solution untouched (just redefined what had to be generalized for the second one) and much of my time went to generalize the neighbors function, just because it seemed fun

euccastro 2020-12-17T06:25:15.338800Z

and yeah, my cycle function would be neater had I realized that cells with 3 neighbors are always activated, whether they were already or not

erwinrooijakkers 2020-12-17T06:30:06.339200Z

Naive brute force (checking every neighbour for every point in every iteration) finished in 15 minutes or so for second part while I tried to optimize in the mean time https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2020/day17.clj Not sure how to optimize though, maybe stop counting when it’s more than 3? Any other suggestions? I’ll take a look later.

πŸ‘ 1
erwinrooijakkers 2020-12-17T06:31:24.339700Z

AH maybe use keep-indexed and not store \. as false to start with πŸ™‚

rjray 2020-12-17T06:31:30.339900Z

Pure brute force for today: https://github.com/rjray/advent-2020-clojure/blob/master/src/advent_of_code/day17.clj

πŸ‘ 1
rjray 2020-12-17T06:31:53.340200Z

I've thought of a way to avoid looping over the entire coordinate system, but it'll have to wait until tomorrow after I've slept.

2020-12-17T06:39:15.340400Z

I solved it. My problem was just that the text did not mention that the slides of the examples were shifted down by 1.

πŸ‘ 3
Aleks 2020-12-17T06:49:00.341100Z

@vincent.cantin Yes, it isn’t illustrated. Sometimes it can give you wrong assumptions. Actually I didn’t look at the examples, because the description was enough to me today.

Aleks 2020-12-17T06:53:47.341400Z

Who wants more, here you go :)) https://adventofcode.com/2019/day/24

πŸ‘ 1
2020-12-17T07:37:47.342300Z

I will keep it for january

peterc 2020-12-17T07:46:42.344Z

@vincent.cantin love your solution, learned a lot from it, ty!

2020-12-17T07:47:41.344200Z

Seriously ?? Which part?

2020-12-17T07:48:47.344400Z

TIL from @zelark

Aleks 2020-12-16T18:49:20.333Z

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

2
βž• 3
peterc 2020-12-16T02:08:29.302300Z

@peterc has joined the channel

st3fan 2020-12-16T02:36:18.303100Z

I got Day 15 Part 2 down to 450ms

st3fan 2020-12-16T02:36:54.303300Z

Rewrote it in C πŸ˜‰

st3fan 2020-12-16T02:37:08.303600Z

Will do a similar solution in Clojure though

Aleks 2020-12-16T06:29:06.307800Z

Day 16 answers thread - Post your answers here

Aleks 2020-12-16T08:08:45.312500Z

Not long, but a bit dirty solution. Will try to refact it after work. https://github.com/zelark/AoC-2020/blob/master/src/zelark/aoc_2020/day_16.clj

πŸ‘ 2
nbardiuk 2020-12-16T09:29:33.313300Z

I am glad that today's problem does not require some fancy dynamic programming algorithm https://github.com/nbardiuk/adventofcode/blob/master/2020/src/day16.clj

πŸ‘ 2
genmeblog 2020-12-16T11:33:24.315700Z

True, but was much complicated than I thought at the beginning... https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2020/day16.clj

πŸ‘ 2
benoit 2020-12-16T14:04:40.316800Z

Nothing very exciting to see here πŸ™‚ https://github.com/benfle/advent-of-code-2020/blob/main/day16.clj

πŸ‘ 2
benoit 2020-12-16T14:05:37.317200Z

Maybe the only interesting bit is to sort the candidates for part2 so you can solve the problem in one pass in a reduce.

πŸ‘ 2
Joe 2020-12-16T14:46:08.322700Z

https://github.com/RedPenguin101/aoc2020/blob/main/day16.clj- I'm pretty happy with my implementation for once. Short, fast(ish) and a comprehensible api. I especially like the narrow-down function here, I thought that was going to much more difficult than it turned out to be.

πŸ‘ 2
Joe 2020-12-16T14:47:26.323200Z

Really fun puzzle too, I like this sort of thing much more than implementing efficient algorithms or fiddling with bits πŸ˜‘

misha 2020-12-16T15:02:00.324800Z

@me1740 how is sorting = one pass? kappa

erwinrooijakkers 2020-12-16T16:21:29.325200Z

I overlooked Now that you've identified which tickets contain invalid values, _discard those tickets entirely_

erwinrooijakkers 2020-12-16T16:22:10.325400Z

And it was bit more difficult than I thought (could not discard the non β€œdeparture” entries)

erwinrooijakkers 2020-12-16T16:22:47.326300Z

Anyway, https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2020/day16.clj

πŸ‘ 1
benoit 2020-12-16T17:04:09.327200Z

@misha sort by the number of candidates for each position. The first position will only have one candidate. The second will have two candidates, the one already picked in (1) + a new one which is the solution...

2020-12-16T17:46:33.327500Z

Hi, here is my solution, it runs in 30 msecs on my old computer. https://github.com/green-coder/advent-of-code-2020/blob/master/src/aoc/day_16.clj

πŸš€ 3
euccastro 2020-12-16T18:06:33.328Z

@benoit is that guaranteed, or did it just happen to be true for the challenge input?

euccastro 2020-12-16T18:07:08.328200Z

I imagine you could have several positions with the same number of candidates, and not the first one would resolve first?

βž• 1
euccastro 2020-12-16T18:08:31.328500Z

my solution just does brute force since it works ~instantly anyway. I didn't clean it up, sorry:

(ns advent.day16
  (:require [clojure.string :as str]
            [ :as io]))


(def demo-input "class: 1-3 or 5-7
row: 6-11 or 33-44
seat: 13-40 or 45-50

your ticket:
7,1,14

nearby tickets:
7,3,47
40,4,50
55,2,20
38,6,12")


(defn parse-long [x]
  (Long/parseLong x))


(defn extents [input]
  (for [[_ & extents]
        (re-seq #"(\d+)-(\d+)" input)]
    (mapv parse-long extents)))


(defn nearby-tickets [input]
  (-> input
      (str/split #"nearby tickets:\n")
      second
      (str/split #"\R")
      (->> (map #(str/split % #","))
           (map #(mapv parse-long %)))))


(defn nearby-ticket-numbers [input]
  (flatten (nearby-tickets input)))


(defn valid-number? [n extents]
  (first (for [[begin end] extents
               :when (<= begin n end)]
           n)))


(defn invalid-numbers [input]
  (let [extents (extents input)]
    (remove #(valid-number? % extents) (nearby-ticket-numbers input))))


(defn solution [input]
  (apply + (invalid-numbers input)))


(solution demo-input)
;; => 71


(def real-input (slurp (io/resource "input16")))


(solution real-input)
;; => 21978

;; part 2


(defn attr-extents [input]
  (for [[_ attr & extents]
        (re-seq #"(\w+\s*\w*):\s+(\d+)-(\d+)\s+or\s+(\d+)-(\d+)" input)]
    (apply vector attr (map parse-long extents))))

(comment

  (attr-extents demo-input)

  )

(defn valid-ticket? [numbers extents]
  (every? #(valid-number? % extents) numbers))


(defn valid-nearby-tickets [input]
  (let [extents (extents input)]
    (filter #(valid-ticket? % extents) (nearby-tickets input))))


(comment
  (def valid-tickets* (valid-nearby-tickets demo-input (extents demo-input)))
  (def attr-extents* (attr-extents demo-input))
  (def num-positions (count (first valid-tickets*)))
  )


(defn attr-matches-position? [[_ begin1 end1 begin2 end2] position tickets]
  (every?
   #(or (<= begin1 % end1) (<= begin2 % end2))
   (map #(nth % position) tickets)))


(defn initial-state [aexts tickets]
  (vec
   (for [pos (range (count aexts))]
     (set (keep
           (fn [[attr :as attr-ext]]
             (when (attr-matches-position?
                    attr-ext
                    pos
                    tickets)
               attr))
           aexts)))))


(defn resolve-positions [initial-state]
  (let [num-positions (count initial-state)]
    (loop [state initial-state]
      (let [resolved (map
                      first
                      (filter #(= (count %) 1)
                              state))
            resolved-set (set resolved)]
        (if (= (count resolved) num-positions)
          resolved
          (recur
           (map
            (fn [x]
              (if (= (count x) 1)
                x
                (remove resolved-set x)))
            state)))))))


(def resolved
  (resolve-positions
   (initial-state
    (attr-extents real-input)
    (valid-nearby-tickets real-input))))


(defn my-ticket [input]
  (-> input
      (str/split #"ticket")
      second
      (->> (re-seq #"\d+")
           (map parse-long))))

(def m (zipmap resolved (my-ticket real-input)))


(apply * (vals (select-keys m (filter #(str/starts-with? % "departure") (keys m)))))
;; => 105368685

πŸ‘ 1
euccastro 2020-12-16T18:08:42.328700Z

names and factoring are very questionable, sorry

euccastro 2020-12-16T18:11:32.329Z

btw this is the first day I actually worked through the problem myself. so far I've just binge-watching @plexus's recorded videos (haven't caught up yet)

pez 2020-12-16T18:15:22.330Z

Step 1 done. Turns out my solution is not as applicable to step 2 as things were yesterday πŸ˜ƒ

(->> input
       (parse)
       ((fn [notes]
          (let [valid? (reduce (fn [acc rule]
                                 (->> (:ranges rule)
                                      (map (fn [[start end]]
                                             (into #{} (range start (inc end)))))
                                      (apply (partial clojure.set/union acc))))
                               #{}
                               (:rules notes))]
            (filter (complement valid?) (apply concat (:nearby notes))))))
       (apply +))

😁 5
2020-12-16T18:45:22.331800Z

I am up to date with the puzzles ^_^

πŸŽ‰ 2
markw 2020-12-16T19:57:15.333600Z

Will probably try to do some cleanup, time permitting: https://github.com/Solaxun/aoc2020_clj/blob/main/src/aoc2020_clj/day16.clj

erwinrooijakkers 2020-12-16T20:29:33.333900Z

How do I turn this into valid core.logic?

(run* [q]
  (fresh [i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20]
    (logic/== q [i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20])
    (fd/in i0 i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 (fd/interval 0 21))
    (logic/membero i0 #{1 2 3 5 6 8 10 11 14})
    (logic/membero i1 #{0 1 2 3 4 5 6 8 10 11 14 15})
    (logic/membero i2 #{0 1 2 3 4 5 6 7 8 10 11 14 15 18 19})
    (logic/membero i3 #{1 2 3 4 5 6 8 10 11 14})
    (logic/membero i4 #{0 1 2 3 4 5 6 8 10 11 14})
    (logic/membero i5 #{6 8 10 11})
    (logic/membero i6 #{6 8 11})
    (logic/membero i7 #{1 5 6 8 10 11 14})
    (logic/membero i8 #{6 8 10 11 14})
    (logic/membero i10 #{1 2 5 6 8 10 11 14})
    (logic/membero i11 #{6 8})
    (logic/membero i12 #{1 6 8 10 11 14})
    (logic/membero i13 #{8})
    (logic/membero i14 #{0 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19})
    (logic/membero i15 #{0 1 2 3 4 5 6 7 8 10 11 14 15 17 18 19})
    (logic/membero i16 #{0 1 2 3 4 5 6 7 8 10 11 14 15 16 17 18 19})
    (logic/membero i17 #{0 1 2 3 4 5 6 7 8 10 11 12 14 15 16 17 18 19})
    (logic/membero i18 #{0 1 2 3 4 5 6 8 10 11 14 15 19})
    (logic/membero i19 #{0 1 2 3 4 5 6 8 10 11 14 15 18 19})
    (logic/membero i20 #{0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19})))

;=> ()...

erwinrooijakkers 2020-12-16T20:29:55.334100Z

This does not make sense

erwinrooijakkers 2020-12-16T20:31:15.334400Z

I’ll ask in core.logic

peterc 2020-12-16T21:44:47.334700Z

@euccastro @me1740 I also did the sort approach as I did it for speed. 1. Inspect the results after you removed the invalid fields for each position. There are some clues that a relatively "simple" solution can be used. 2. Next, sort the valid fields by count and do a set difference between each element to see that there is indeed a unique solution. Obviously a solution is not guaranteed, but step two is quick to test.

πŸ‘ 2
rjray 2020-12-16T06:57:37.308Z

Long solution. I also plan to try to improve it. Tomorrow. https://github.com/rjray/advent-2020-clojure/blob/master/src/advent_of_code/day16.clj

πŸ‘ 1
πŸŽ‰ 2