This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-12-02
Channels
- # adventofcode (76)
- # announcements (1)
- # asami (1)
- # babashka (31)
- # beginners (302)
- # calva (3)
- # cider (1)
- # clj-kondo (1)
- # cljdoc (1)
- # cljfx (63)
- # cljsjs (2)
- # clojure (36)
- # clojure-europe (29)
- # clojure-gamedev (2)
- # clojure-nl (5)
- # clojure-sanfrancisco (2)
- # clojure-spec (2)
- # clojure-uk (71)
- # clojurescript (19)
- # conjure (21)
- # core-async (10)
- # core-matrix (1)
- # cryogen (4)
- # cursive (12)
- # datomic (22)
- # emacs (4)
- # events (1)
- # figwheel-main (7)
- # fulcro (9)
- # graalvm (1)
- # jobs (1)
- # kaocha (17)
- # lambdaisland (1)
- # meander (7)
- # mount (2)
- # nrepl (12)
- # off-topic (35)
- # re-frame (15)
- # reagent (17)
- # remote-jobs (1)
- # reveal (41)
- # shadow-cljs (13)
- # spacemacs (2)
- # tools-deps (24)
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.
Hey are you going to be doing a video series this year for AoC? @U07S8JGF7
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
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
Nice 🙂
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))]))))
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 😃 )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.
I also used a regex, but with groups. I should have splitted instead, had I thought about it. 😀
always forget about slurp and barf, I like how some edits are more fluent with them
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.
https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2020/day2.clj
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 did same as yours initially but then realized clojure had no xor
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
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.
I remember a talk from Clojure Vienna 2016 on ReasonML’s Unikernels and also transforming Clojure to ReasonML: https://youtu.be/tB705w4w6H0

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
@U7JHWBCS0 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 🙂
looks pretty clean
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!
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
If you use GitHub to login
Not sure if that’s possible
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
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. 😃nothing fancy but my day 02 solution https://github.com/listba/advent-of-code-2020/blob/master/clojure/src/aoc_2020/days/02.clj
my also not fancy day 2… I like how declarative it came out looking https://gist.github.com/KennyMonster/eb6ea22eaba1a1a1201820ef1bddc1cf
I put my input-slurper into a gist: https://gist.github.com/PEZ/bcd23b9bc099b8b21a41c8c9de78a0f4
hi there. Here is my day 1 "theorically fast" solution https://github.com/green-coder/advent-of-code-2020/blob/801ebdeb9afa3904c1a5e31aeb9386e30e950c78/src/aoc/day_1.clj#L34
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 fineI 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
trying to get my day1 and day2 solutions finished and pushed
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