adventofcode 2020-12-02

Did anyone else use reduce/`reduced`? It feels dirty but I canโ€™t figure out how to get the same efficiency without it. My other solution was to use some but created the whole set of inputs before hand.

(defn find-ints-summing-to-target [coll]
  (reduce (fn [seen-set n]
            (let [diff (- target-sum n)]
              (if (seen-set diff)
                (reduced #{n diff})
                (conj seen-set n))))
          #{}
          coll))

reduced is totally fine and normal. You use it in exactly this sort of situation: You want to short-circuit evaluation because youโ€™re done.

๐Ÿ‘ 2

Hey are you going to be doing a video series this year for AoC? @potetm

ugh I made the mistake of trying it in rust this year

no one wants to see that ๐Ÿ˜„

I liked how you broke down the problem in the videos regardless of language used. If you do decide to make them, I would take a look

it also returns the whole set if a pair isnโ€™t found which is a terrible result in the negative find case

ah looks like skykanin did something similar above in a cleaner fashion

Today I just threw core.logic with finite domain at it, which worked out quite nice: https://github.com/IamDrowsy/aoc-2020/blob/master/clojure/src/advent_of_code/d01.clj

๐Ÿ‘ 7

Nice ๐Ÿ™‚

@gdwarner has joined the channel

Day 2, not bad, most of the work was processing the input into usable form. E.g.

{:lb 1, :ub 3, :ch \a, :pw "abcde"}
..which took as many loc as my solutions. Here are my pw test functions. Filter input with them and count the results:
(defn pwgood? [{:keys [lb ub ch pw]}]
  (<= lb (get (frequencies pw) ch 0) ub))

(defn pwgood2? [{:keys [lb ub ch pw]}]
  (= 1 (count (filter #(= ch %)
     [(nth pw (dec lb)) (nth pw (dec ub))]))))

That is beautiful!

Mine:

(defn checks? [{:keys [p1 p2 ch pwd]}]
  (as-> pwd $
    (filter #(= ch %) $)
    (count $)
    (<= p1 $ p2)))

(defn checks2? [{:keys [p1 p2 ch pwd]}]
  (let [p1 (dec p1)
        p2 (dec p2)]
    (as-> pwd $
      (seq $)
      (vec $)
      (not= (= ($ p1) ch) (= ($ p2) ch)))))
(I didnโ€™t bother to update the parser between the two ๐Ÿ˜ƒ )

๐Ÿ‘ 1

Neither did you, I now realize. Haha.

@dgtized has joined the channel

@dromar56 has joined the channel

I am curious what did you you use to parse data for Day 2. Have you used regexp or some nice parser combinator library?

A small regex. I simply split each line with #(str/split % #โ€œ[- :]โ€œ) and then converted the strings to numbers and chars as appropriate.

๐Ÿ‘ 1

I also used a regex, but with groups. I should have splitted instead, had I thought about it. ๐Ÿ˜€

@plexus has joined the channel

My solution for day 2 https://youtu.be/rghUu4z5MdM

๐Ÿ‘ 3

always forget about slurp and barf, I like how some edits are more fluent with them

โž• 1

I mapped my forward/backward slurp/barf in a positional way on my keyboard, to forget their names and remember what they do.

Watched it now. Super nice. You are so fluent in both how you talk and how you code, making it a pleasant experience.

Thank you ๐Ÿ˜Š

My day 2 part 1 was pretty similar to yours

(defn parse-line [s]
  (let [splits (rest (re-find #"(\d+)-(\d+)\s(.):\s(.+)" s))]
      {:range [(Integer/parseInt (first splits)) (Integer/parseInt (second splits))]
       :char (first (nth splits 2))
       :password (last splits)}))

;; check valid for part 1
(defn valid-password? [{:keys [range char password]}]
  (let [[min max] range
        freq       (frequencies password)
        char-count (freq char 0)]
    (<= min char-count max)))

;; check valid for part 1
(defn valid-password? [{:keys [range char password]}]
  (let [p1 (nth password (dec (first range)) \_)
        p2 (nth password (dec (second range)) \_)]
    (or (and (= char p1) (not= char p2))
        (and (not= char p1) (= char p2)))))

(->> (slurp "input.txt")
     (str/split-lines)
     (map parse-line)
     (filter valid-password?)
     (count))

I like your solution for part2!

๐Ÿ™‚ i did same as yours initially but then realized clojure had no xor

@pez has joined the channel

Has someone figured out a way to slurp the input data directly from the site? Iโ€™m lazy, so if someone has this solved in a nice module, Iโ€™d love to have it. ๐Ÿ˜ƒ Iโ€™m also not lazy, so if this is not done by someone, I might try to do it, if someone here does not tell me it is probably very hard. And Iโ€™m the sharing type. Haha.

There is some Python program somewhere

aocd > input.txt  # saves today's data
aocd 13 2018 > day13.txt  # save some other day's data

If I end up rolling this, Iโ€™ll have use for that to see what is involved.

Was attempting to do so yesterday, then I realised authentication is required

lazy way I think would be doing it first from the browser, "copy as cURL" so that it has your cookie headers in there, then you can adjust that curl line to download the other ones as long as your session remains valid

In the Python aocd tool you can add the value of the session cookie in the AOC_SESSION env var or ~/.config/aocd/token file

Wow as always itโ€™s fascinating to watch Clojurians solution in this channel. This year Iโ€™m using ReasonML(family of OCaml) since my company has chosen it. https://github.com/namenu/advent-of-reason/blob/master/src/Year2020/Year2020_Day01.res Yes, itโ€™s typed, I miss Clojure so badly.

๐Ÿ‘ 1

I remember a talk from Clojure Vienna 2016 on ReasonMLโ€™s Unikernels and also transforming Clojure to ReasonML: https://youtu.be/tB705w4w6H0

1

Wow thats... cursed

haha

Was pretty interesting stuff. Booting up a unikernel faster than the time it takes to do a TCP handshake

Not sure what the status is of it now

@namenu lol your ReasonML is gone? In favour of https://github.com/namenu/advent-of-code/tree/master/src? ๐Ÿ˜„

aah I see itโ€™s still Reason ๐Ÿ™‚

nice

looks pretty clean

oh yes I merged the ReasonML repo with Clojure's to contrast them

I found ML language interesting in a way that more lengthy code makes a program safer, because compiler is very very smart. In my experience, this wasn't true in Clojure. I always prefer brevity in my code, because more code means more bugs!

๐Ÿ‘ 1

I use ReasonML and Clojure both for living, and they are both great in very different ways

Maybe a program can login via the GitHub SSH key so that you donโ€™t need the session

โค๏ธ 1

If you use GitHub to login

Not sure if thatโ€™s possible

@joetague has joined the channel

just need to find the session id with devtools and put a export AOC_SESSION=... in your shell profile

And in the same way, it's also pretty easy to get the input via clojure (I just store the session in a file) https://github.com/IamDrowsy/aoc-2020/blob/581097350d2dc7865304ffc9eddaf6a479406ca1/clojure/src/advent_of_code/util.clj#L9:L13

Neat! Found this a bit late, but I did exactly that. ๐Ÿ˜ƒ

@johnny has joined the channel

@mrichards has joined the channel

Decided to go the easy path that @plexus pointed out. Copy as cURL from the problem page when I start reading it-> Grab the session cookie there -> (set-fetch-cookie! "<cookie>") -> Hack away until I need the input -> (util/fetch-input <day>)

(ns pez.aoc2020.util
  (:require [clj-http.client :as client]))

(def ^:dynamic *fetch-cookie* "")

(defn set-fetch-cookie! [cookie]
  (alter-var-root #'*fetch-cookie* (constantly cookie)))

(defn fetch-input [day]
  (if (seq *fetch-cookie*)
    (try
      (:body (client/get
              (str "" day "/input")
              {:cookies {"session" {:value *fetch-cookie*}}}))
      (catch Exception e
        (println "Ho, ho, ho! Did you forget to `set-fetch-cookie!`?")
        (throw e)))
    (throw (Exception. "Ho, ho, ho! You forgot to `set-fetch-cookie!` first."))))
Like so:
(comment
  (def input
    "1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc")
  (util/set-fetch-cookie! "retracted")
  (def input (util/fetch-input 2))
  (->> input
       (parse)
       (filter checks2?)
       (map :pwd)
       (count)))
Not sure how long the cookie lives, but it should live long enough even for my slow solution pace. And if not, accept that I suck and grab a new session cookie. Iโ€™ll see in 11 hours and 47 minutes how much I like this workflow. ๐Ÿ˜ƒ

Last year the session never changed.

I've just checked that cookie expiration is set for 10 years ๐Ÿ˜

Even I should be able to solve the puzzles in that time!

I am stuck in 2016 somewhere, not sure 10 years will cut it for me ๐Ÿ˜‰

my also not fancy day 2โ€ฆ I like how declarative it came out looking https://gist.github.com/KennyMonster/eb6ea22eaba1a1a1201820ef1bddc1cf

๐Ÿ‘ 2

this is probably more a #beginners question, but figured Iโ€™d ask here since itโ€™s related to the Advent of Code stuff Iโ€™m trying why isnโ€™t this working? I copied problem 1's input file to a file called input in resources (in a Leinengen app template project)

(slurp (io/resource "input"))
when run via lein exec my_script.clj, I get java.lang.IllegalArgumentException: Cannot open <nil> as a Reader. however, doing the exact same thing in lein repl works fine

I don't use the exec plugin, but looks like it has -p flag that runs the script in project CLASSPATH, wich is required to resolve the resources

https://github.com/kumarshantanu/lein-exec

-p  indicates the script should be evaluated in project (with classpath)

thank you! that was it

ha, funny seeing you here @jeffrey.wayne.evans

๐Ÿ˜€ 1

trying to get my day1 and day2 solutions finished and pushed

I am learning clojure too, trying to do AOC with it

sweet! letโ€™s keep each other accountable

๐Ÿ™Œ 1

Ive got my solutions here, finished day 1 and 2! https://github.com/kwpav/advent-of-code-2020

nice! Iโ€™m a bit behind, only got day 1 done so far: https://github.com/jeff303/advent-of-code-2020

gonna try to finish day 2 before I look at yours

yeah, almost seems easier, especially with Clojure. though Iโ€™m sure part 2 will throw some kind of wrench into it

@kpavao84 has joined the channel

@ola.sikstrom has joined the channel