adventofcode

2020-12-06T05:17:56.309800Z

Good morning !

๐Ÿ˜ 4
fingertoe 2020-12-06T05:38:23.312500Z

Hello! Todayโ€™s problem was pretty straightforward.. I am tied with the amount of problems I finished last year.. Not close to burning out.. I wonder if it is going easy on us this year?

2020-12-06T05:58:26.314100Z

I am awaiting the difficult problems like a surfer awaiting its wave.

Aleks 2020-12-06T05:59:20.314900Z

You can pick one from the last year ^_^

๐Ÿ‘ 1
๐Ÿ’ฏ 1
2020-12-06T06:03:36.316100Z

I will keep them for January.

mchampine 2020-12-06T05:58:36.314400Z

Agree! #6 usually starts ramping way up.

kenj 2020-12-06T05:59:25.315200Z

why give us a difficult problem on the weekend when you can save it for a weekdayโ€ฆ

๐Ÿ˜† 2
2020-12-06T06:00:17.315800Z

During the first 1 min 30, I was staring at a blank page, waiting for the page to load.

plexus 2020-12-06T06:13:10.317100Z

AoC really starts the first time you add

(set! *unchecked-math* :warn-on-boxed)
(set! *warn-on-reflection* true)
to a namespace

๐Ÿ‘Ÿ 1
๐Ÿƒโ€โ™‚๏ธ 1
๐Ÿ˜ 3
2020-12-06T06:23:33.319200Z

I like @dosโ€™s solution, which did not separate the input loading from the processing for the solution. It might be faster to type in that way.

james 2020-12-06T06:31:21.320700Z

This is the first year I'm (seriously) trying to do this. Does it usually get harder day by day?

james 2020-12-06T06:34:36.322700Z

(Today's puzzle was pretty easy, but if they're going to get difficult I might not have time to see it through.)

markw 2020-12-06T06:34:57.323Z

Problems have been surprisingly simple so far this year

markw 2020-12-06T06:35:13.323500Z

Last year for me, was by far the most difficult of them all

Aleks 2020-12-06T06:36:10.324300Z

Thatโ€™s probably because weโ€™re going to vacation ๐Ÿ˜ƒ

๐Ÿ˜„ 1
markw 2020-12-06T06:37:36.324900Z

that or heโ€™s lulling us into complacency just before dropping the hammer tomorrow

markw 2020-12-06T06:37:57.325300Z

oh you got work Monday morning? Hope you remember A* search

๐Ÿ˜ 4
plexus 2020-12-06T06:40:40.326700Z

I skipped AoC last year because the year before I ended up spending sometimes multiple hours on a single solution. If it gets like that again I'm out, but a bit more challenging than today's would be nice too ๐Ÿ™‚

markw 2020-12-06T06:41:09.327700Z

Iโ€™ve done them since 2015, finished most but not all of them.. Except last year i bailed very early

plexus 2020-12-06T06:41:34.328600Z

Today's video: https://www.youtube.com/watch?v=b0a5siw85N4&feature=youtu.be I also talk a bit about the different ways that people solved yesterday's puzzle

๐Ÿ‘ 2
plexus 2020-12-06T06:42:34.329500Z

Many thanks to folks who dropped into the live chats or left comments!

2020-12-06T07:22:42.332100Z

Let me know if I leave too many comments during the streaming ๐Ÿ˜… I have a hard time holding them while excited by the contest.

plexus 2020-12-06T07:56:58.333200Z

All good, it's nice to see some activity :)

markw 2020-12-06T06:41:37.328800Z

they definitely get difficult and I was spending hours on problems routinely, but iโ€™m not a fast solver

markw 2020-12-06T06:42:34.329400Z

last year by like day 14 you had implemented a VM for a made up language, and then implemented pong using that language

james 2020-12-06T06:45:06.329800Z

Cool.

james 2020-12-06T06:45:39.330600Z

I'm not a fast solver either, and also I'm doing them in Clojure, which I don't really know, so I'm extra slow.

markw 2020-12-06T06:46:11.331200Z

i know the feelingโ€ฆ iโ€™m trying to go back and do them in Go after I finish in Clojure, and it is โ€ฆ painful (i donโ€™t know Go)

markw 2020-12-06T06:46:21.331400Z

lots of typing

devn 2020-12-06T10:34:05.334300Z

Day 6 Answers Thread - Post your answers here

devn 2020-12-06T10:34:57.334400Z

(ns day6
  (:require [clojure.string :as str]
            [clojure.set :as set]))

(def input "...")

(def groups (str/split input #"\n\n"))

;; Part I
(apply + (for [group groups] (count (distinct (str/replace group #"\n" "")))))

;; Part II
(apply + (for [group groups
               :let [people (str/split-lines group)
                     answer-sets (map set people)]]
           (count (apply set/intersection answer-sets))))

tschady 2020-12-06T10:53:28.335100Z

(ns aoc.2020.d06
  (:require [aoc.file-util :as file-util]
            [clojure.set :refer [intersection]]
            [clojure.string :as str]))

(def input (map str/split-lines (file-util/read-chunks "2020/d06.txt")))

(defn part-1 [input]
  (reduce + (map (comp count distinct (partial apply str)) input)))

(defn part-2 [input]
  (reduce + (map (comp count (partial apply intersection) (partial map set)) input)))

tschady 2020-12-06T10:53:45.335300Z

first pass, feels inelegant

devn 2020-12-06T10:59:02.335800Z

i feel the same way, but ๐Ÿคท

devn 2020-12-06T11:00:43.336Z

im guessing thereโ€™s a frequencies-based solution

nbardiuk 2020-12-06T11:31:26.336200Z

Also checkout pinned thread for day 6 https://clojurians.slack.com/archives/C0GLTDB2T/p1607104763255500?thread_ts=1607104763.255500&cid=C0GLTDB2T

๐Ÿ‘ 1
benoit 2020-12-06T12:54:58.337400Z

I misread part1 and actually solve part2 first ๐Ÿ™‚ https://github.com/benfle/advent-of-code-2020/blob/main/day6.clj

st3fan 2020-12-06T16:08:29.339800Z

@djblue nice ... (str/split input #"*\n\n*") that did not occur to me, I do a (partition-by empty?) ๐Ÿ™‚

๐Ÿ’ฏ 1
1
Narve Saetre 2020-12-06T20:16:19.341900Z

Noob code coming up - but I am actually quite happy with this code, it reads nicely I think:

(defn count-group [group]
  (->> group
       (string/split-lines)
       (map set)
       (apply clojure.set/intersection)
       (count)))

(->> (string/split (slurp "adv6.input.txt") #"\n\n")
     (map count-group)
     (reduce +))

Narve Saetre 2020-12-06T20:18:55.342100Z

I love the -> and ->> macros, but sometimes they can't be used because the place to put the previous form is different ... any tips for that particular problem? Is there a -?> which "does the right thing depending on the form ๐Ÿ˜„

Narve Saetre 2020-12-06T20:28:46.342300Z

Answering my self: I just searched and found as->, a very nice function. This allows me to write e.g.

(as-> "adv6.input.txt" v
      (slurp v)
      (string/split v #"\n\n")
      (map count-group v)
      (reduce + v))

tschady 2020-12-06T22:55:05.345Z

@narve YMMV, but I try not to use as->, I find it has maintenance problems for me. I like to just pull out the different one as a let, so thereโ€™s only 1 threading type. In this case, could do:

(let [groups (-> path slurp (str/split #"\n\n")]
  (->> groups...))

Narve Saetre 2020-12-07T06:44:08.348200Z

yeah, I c your point. I can also use minor (-> or (->> lines within the larger thread-block as well. Just gotta pick the right tool for the job ๐Ÿ™‚

st3fan 2020-12-06T16:06:41.339200Z

Day 7 Answers Thread - Post your answers here

devn 2020-12-08T19:40:36.405400Z

@zelark is my hero. his solution in this thread blows me away.

โž• 2
devn 2020-12-08T19:49:07.405800Z

I didnโ€™t finish Part II in this style yet, but I decided to try and do day7 in a rules engine (#clara). Thereโ€™s a better way to write this, but this gets the right answer:

(defrecord ContainerBag [type contained-bags])
(defrecord IntermediateBag [parent-type type])
(defrecord GoldBag [parent-type])

(defrule produce-intermediate-bags
  [ContainerBag
   (= ?type type)
   (= ?contained-bags contained-bags)]
  =>
  (when (seq ?contained-bags)
    (insert-all!
     (mapv (fn [[kind num]]
             (if (= kind "shiny gold")
               (map->GoldBag {:parent-type ?type})
               (map->IntermediateBag {:parent-type ?type
                                      :type kind})))
           ?contained-bags))))

(defrule indirect-gold-bags
  [ContainerBag
   (= ?type type)]
  [IntermediateBag
   (= ?type parent-type)
   (= ?intermediate-type type)]
  [GoldBag
   (= ?intermediate-type parent-type)]
  =>
  (insert! (map->GoldBag {:parent-type ?type})))

(defquery gold-bags []
  [?gold-bags <- (acc/distinct :parent-type) :from [GoldBag]])

(defn run-rules []
  (-> (mk-session :cache false)
      (insert-all (doall (for [[k vs] (parse input)]
                           (map->ContainerBag {:type k
                                               :contained-bags vs}))))
      (fire-rules)))
;; Part I
(-> (run-rules)
    (query gold-bags)
    first
    :?gold-bags
    count)
;; => 179

devn 2020-12-08T19:52:27.406100Z

It would be cool to dynamically generate defrules for each line

2020-12-07T06:42:32.347800Z

I need to improve my regex capture skills. Let me know if you have a fast way to do the parsing/capturing, I am interested to learn.

Aleks 2020-12-07T06:55:56.348400Z

not ideal, but I came up with this for parsing

(defn parse-entry [entry]
  (let [p  (re-find #"\w+ \w+" entry)
        cs (->> (re-seq #"(\d+) (\w+ \w+)" entry)
                (reduce (fn [m [_ v k]] (assoc m k (Long/parseLong v))) {}))]
    [p cs]))

(def bags (into {} (map parse-entry (str/split-lines input))))

2020-12-07T07:41:34.348800Z

I just realized that the algorithm for part2 could be used for part1

oxalorg (Mitesh) 2020-12-07T07:56:35.349100Z

My naive solution: https://github.com/oxalorg/aoc/blob/main/src/puzzle7.clj Using some kind of memo could speed up first pass, but this works! ^_^

Aleks 2020-12-07T08:03:50.349600Z

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

๐Ÿ‘ 2
erwinrooijakkers 2020-12-07T08:18:00.352Z

Mine:ย https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2020/day7.clj I donโ€™t know why exactly I had to call set on the tree-seq entries in part 1 nor why I had to do apply + 1 in part 2, but it worksย ๐Ÿ™‚

โค๏ธ 2
2020-12-07T08:18:25.352400Z

I forgot about tree-seq โ€ฆ thatโ€™s a good idea.

erwinrooijakkers 2020-12-07T08:28:26.353Z

๐Ÿ™‚ i now see set is because you have to find amount of different colors and + 1 is because you also have to count the containing bag

erwinrooijakkers 2020-12-07T08:30:32.354100Z

(into (set found-bags) (mapcat #(find-outer-bags bags %) found-bags)) nice @zelark

๐Ÿ˜ 1
โž• 1
2020-12-07T08:46:18.355200Z

I used this one as an https://github.com/ocisly/advent2020/blob/a96bd7be5e961d737bf33bc552724542e9e65d02/day-7.clj#L19-L41 to learn core.logic... ๐Ÿ˜ฌ

๐Ÿ‘ 3
๐Ÿ‘ 1
erwinrooijakkers 2020-12-07T09:05:55.355900Z

Wow nice, I tried to use core.logic last year for a somewhat similar problem (https://adventofcode.com/2019/day/14) but I did not manage

๐Ÿ‘ 1
Aleks 2020-12-07T09:30:57.356400Z

@erwinrooijakkers thanks to your solution for part 2, I simplified mine. Now itโ€™s pretty straightforward

(defn count-bags [bags [bag n]]
  (* n (apply + 1 (map #(count-bags bags %) (get bags bag)))))

๐Ÿ˜Š 2
nbardiuk 2020-12-07T09:32:51.356600Z

don't have good intuition for graphs, always struggle https://github.com/nbardiuk/adventofcode/blob/master/2020/src/day07.clj

Dos 2020-12-07T09:34:20.357100Z

(loop [bags #{"shiny gold"}
       old-bags #{}]
  (if (= bags old-bags)
    (dec (count bags))
    (let [new-bags (into bags (map first
                                   (filter #(seq (clojure.set/intersection bags (second %))) data)))]
      (recur new-bags bags))))

Dos 2020-12-07T09:36:02.357500Z

(defn get-bags-inside [times [color amount]]
  [(mapv (partial get-bags-inside (* times amount)) (data color)) (* times amount)])

(dec (apply + (flatten (get-bags-inside 1 ["shiny gold" 1]))))

benoit 2020-12-07T13:45:42.362500Z

Nothing very exciting in my solution but I will post anyway ๐Ÿ™‚ https://github.com/benfle/advent-of-code-2020/blob/main/day7.clj It took me way too long to figure out I was off by one for part 2 because I was counting the top shiny gold bag :)

tschady 2020-12-07T14:15:15.363200Z

using loom: https://github.com/tschady/advent-of-code/blob/master/src/aoc/2020/d07.clj

๐Ÿ‘ 1
2020-12-07T15:15:03.363600Z

What am I missing with this regex? Works fine for groups of 1 or two but fails with 3 or more (the second group gets improperly matched)

(\w+ \w+) bags? contain ((\d+) (\w+ \w+).*? bags?)(, (\d+) (\w+ \w+) bags?)*\.

tschady 2020-12-07T15:19:57.363800Z

the * doesnโ€™t repeat the capture group like you think it does

tschady 2020-12-07T15:26:49.365100Z

iโ€™d consider re-seq

Aleks 2020-12-07T15:45:57.366600Z

visualization >_< https://i.redd.it/gx6l9oavzp361.jpg

๐Ÿ˜‚ 4
Aleks 2020-12-07T15:56:03.367Z

> What am I missing with this regex? @jculp if you repeat a group, this group will be overwritten by the next match. For such cases you need to split a line, or just write 2 regex. Check my solution above for example.

Ben List 2020-12-07T16:59:20.368700Z

heres mine, O'm definitely interested to see what others came up with today as I'm fairly new to clojure still https://github.com/listba/advent-of-code-2020/blob/master/clojure/src/aoc_2020/days/07.clj

rjray 2020-12-07T20:02:27.370600Z

Here's mine: https://github.com/rjray/advent-2020-clojure/blob/master/src/advent_of_code/day07.clj Writing the parsing took longer than I'd like, but I really got stuck in part 1 due to a small logic-error. Part 2 only took about 10 more minutes.

Joe 2020-12-07T20:55:46.372100Z

https://redpenguin101.github.io/posts/2020_12_07_aoc2020_day7.html. So impressed at how concise some of the answers here are. That was a fun problem though!

โž• 1
mchampine 2020-12-07T23:09:07.376Z

Again, lots of effort spent on processing the raw input into a nice shape. I notice my part 2 recursive function has the same pattern as several others. Took me some grinding to get it working. Still not pretty, oh well.

;; with input processed as:
;;     ["dull aqua" ([4 "dark fuchsia"] [1 "shiny purple"])]
(defn count-nestedbags [inp topbag]
  (letfn [(rcount [bag]
            (let [[_ bt] bag
                  contained (second (first (filter #(= bt (first %)) inp)))]
              (apply + 1
                     (for [[bc bn :as thebag] contained]
                       (if (= bn "no other") bc
                         (* bc (rcount thebag)))))))]
    (dec (rcount [1 topbag]))))

(count-nestedbags input-part2 "shiny gold")

pez 2020-12-07T23:15:07.376500Z

This was so hard for me. It took me a lot of time to realize my first regex approach would not work. Then I had struggles wrapping my head around the recursion I needed. Then I made all sorts of silly mistakes even though the structure was rightโ€ฆ And the result aint pretty!

(comment ; step 1
  (def input (util/fetch-input 7))
  (->> (clojure.string/split-lines input)
       (map #(clojure.string/split % #"[ ,]"))
       (map #(->> %
                  (partition 2 5)
                  (map vec)
                  (map (partial apply str))))
       ((fn dig [look-for found rules]
          (let [directs (reduce (fn [acc [bag & bags]]
                                  (if (seq (clojure.set/intersection (set bags) look-for))
                                    (conj acc bag)
                                    acc))
                                #{}
                                rules)]
            (if (seq directs)
              (dig directs (conj found directs) rules)
              found)))
        #{"shinygold"} #{})
       (apply clojure.set/union)
       (count)))

(comment ; step 2
  (def input (util/fetch-input 7))
  (->> (clojure.string/split-lines input)
       (map #(clojure.string/split (str "1 " %) #"[ ,]"))
       (remove #((set %) "no"))
       (map #(->> %
                  (partition 3 5)
                  (map (fn [[n c1 c2]]
                         [(Integer/parseInt n) (str c1 c2)]))))
       ((fn dig [look-for found rules]
          (let [directs (reduce (fn [acc [[_n bag-color] & bags]]
                                  (->> (for [color look-for
                                             :when (= color bag-color)]
                                         (map #(repeat (first %) %) bags))
                                       (apply concat)
                                       (apply concat)
                                       (into acc)))
                                []
                                rules)]
            (if (seq directs)
              (dig (map second directs) (into found directs) rules)
              found)))
        ["shinygold"] [])
       (count)))

pez 2020-12-07T23:16:42.376700Z

when I have troubles naming things, I know I donโ€™t know what I am doing, but I pressed on on sheer intuition. ยฏ\(ใƒ„)/ยฏ

st3fan 2020-12-06T16:06:48.339500Z

Day 8 Answers Thread - Post your answers here

pez 2020-12-09T21:38:26.486400Z

A reason part 2 took me so long is that I was looking at it as a tree problem. So I was able to build a structure something like so (simplyfied):

[[nop jmp]
 [acc]
 [acc]
 [jmp nop]
 [acc]]
But then I failed building the programs from this. Which for the example above would be:
[[nop acc acc jmp acc]
 [jmp acc acc jmp acc]
 [nop acc acc nop acc]
 [jmp acc acc nop acc]]
Does anyone have any pointers on how to go about it?

2020-12-10T01:41:50.011700Z

@pez Here is what I would do to optimize this problem: โ€ข Collect all the switch-indexes , indexes of the nop and jmp where the original program go before an infinite loop is detected, because the solution is to flip one of those indexes. โ€ข Build the reverse-jmp-graph, where edges are from jmp-targets to jmp-sources. โ€ข In this graph, collect all land-indexes which are reachable from the end of the program. โ€ข Find which change on instructions at switch-indexes let the program go into instructions at land-indexes .

Aleks 2020-12-08T08:06:00.385900Z

And my final solution: https://github.com/zelark/AoC-2020/blob/master/src/zelark/aoc_2020/day_08.clj in the Part 2 firstly I used case , but re-implement it with a hash-map as @plexus showed on the live stream.

fingertoe 2020-12-08T08:27:54.388300Z

I always feel filthy when I use atomsโ€ฆ. This one is pretty dirty, but I got it done: https://github.com/jreighley/aoc2020/blob/master/src/day8.clj

motform 2020-12-08T12:07:40.395300Z

definitely a bit engineered, but Iโ€™m not getting caught off-guard by a part 2: intcode boogaloo https://github.com/motform/advent-of-clojure/blob/master/src/advent-of-clojure/2020/eight.clj

benoit 2020-12-08T12:36:33.396700Z

Looks like most of us have similar approaches. https://github.com/benfle/advent-of-code-2020/blob/main/day8.clj

Lars Nilsson 2020-12-08T15:23:24.399100Z

Day 8 makes me appreciate immutable data structures and defmulti. I am fairly happy with my code for a change. https://github.com/chamaeleon/aoc2020-clj/blob/master/src/aoc2020/day08.clj

Joe 2020-12-08T18:49:00.404400Z

https://redpenguin101.github.io/posts/2020_12_08_aoc2020_day8.html - this one did give me some flashbacks to intcode ๐Ÿ˜จ

๐Ÿ‘ 1
Ben List 2020-12-08T19:30:41.405Z

I really liked the intcode ones last year so I hope there's some future days that build this one up Anyways my solution for day 08 https://github.com/listba/advent-of-code-2020/blob/master/clojure/src/aoc_2020/days/08.clj

pez 2020-12-08T22:44:59.419600Z

I tried for so long do step 2 in a tree-ish way. Gave up. The brute force was with me though. Copying the program and modifying each one differently worked. I want my gold stars! Glad I learned about cond-> the other day.

(defn parse [input]
  (->> (clojure.string/split-lines input)
       (map #(clojure.string/split % #" "))
       (mapv (fn [[op arg]] [op (Integer/parseInt arg)]))))

(defn run [program]
  (let [length (count program)]
    (reduce (fn [cpu _]
              (let [{:keys [pc pcs]} cpu]
                (if (< pc length)
                  (let [[op arg]         (nth program pc)]
                    (if (pcs pc)
                      (reduced cpu)
                      (cond-> cpu
                        (= op "acc")        (update :acc #(+ % arg))
                        (#{"acc" "nop"} op) (update :pc inc)
                        (= op "jmp")        (update :pc #(+ % arg))
                        :always             (update :pcs conj pc))))
                  (reduced cpu))))
            {:acc    0
             :pc     0
             :length (count program)
             :pcs    #{}}
            (range))))

(comment
  (def input (util/fetch-input 8))
  ; step 1
  (->> input
       (parse)
       (run)
       :acc)

  ; step 2
  (->> input
       (parse)
       (#(repeat (count %) %))
       (keep-indexed (fn [i program]
                       (let [[op val] (program i)]
                         (assoc program i [(cond
                                             (= "nop" op) "jmp"
                                             (= "jmp" op) "nop"
                                             :else        op)
                                           val]))))
       (map run)
       (filter #(= (:pc %) (:length %)))
       (first)
       :acc))

๐ŸŽ‰ 1
kenj 2020-12-09T06:30:50.426400Z

Iโ€™m officially a day behind now and late to the party https://gist.github.com/KennyMonster/9b9db6daa056e41413112d0fb31a5e47

kenj 2020-12-09T06:31:10.426600Z

feels like part 2 could be way nice even brute forcing itโ€ฆ but I dunno how

oxalorg (Mitesh) 2020-12-08T06:06:18.380100Z

Todays challenge was super fun! https://github.com/oxalorg/aoc/blob/main/src/day8.clj

2020-12-08T06:34:23.381800Z

It reminds me my old emulator https://github.com/green-coder/girlfriend-advance

๐Ÿฆœ 1
๐ŸŽฎ 5
Aleks 2020-12-08T07:14:32.385400Z

(defn run-code [code]
  (let [history (atom #{})]
    (loop [acc 0
           ip  0]
      (let [[op arg] (nth code ip [:hlt 0])]
        (if (contains? @history ip)
          {:inf-loop acc}
          (do (swap! history conj ip)
              (case op
                :hlt {:halt acc}
                :nop (recur acc (inc ip))
                :acc (recur (+ acc arg) (inc ip))
                :jmp (recur acc (+ ip arg)))))))))

maksut 2020-12-06T16:33:22.340200Z

@maksut.cagil has joined the channel

wil 2020-12-06T19:04:24.340900Z

@wilhelmberggren has joined the channel

2020-12-06T19:08:27.341300Z

I've learnt a few neat functions from looking at you guys solution so far this year ๐Ÿ™‚

๐Ÿ’ฏ 1
tschady 2020-12-06T22:50:58.344700Z

In case you havenโ€™t seen it, I highly recommend being well versed in all these base functions, really helps to know whatโ€™s possible. https://clojure.org/api/cheatsheet

๐Ÿ‘ 1
Lukas 2020-12-06T21:22:32.342700Z

@lukas.block has joined the channel

st3fan 2020-12-06T22:46:35.344200Z

I am doing 2015 in parallel ๐Ÿ˜•

2020-12-07T06:43:24.348Z

split keyboard? ๐Ÿ˜‰