This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-30
Channels
- # adventofcode (95)
- # announcements (17)
- # babashka (28)
- # beginners (107)
- # calva (34)
- # clj-kondo (7)
- # cljs-dev (20)
- # cljsrn (1)
- # clojure (95)
- # clojure-europe (41)
- # clojure-italy (3)
- # clojure-nl (5)
- # clojure-spec (7)
- # clojure-uk (4)
- # clojurescript (77)
- # cursive (7)
- # data-science (1)
- # datalog (4)
- # datomic (12)
- # events (3)
- # fulcro (32)
- # graalvm (2)
- # hugsql (19)
- # introduce-yourself (4)
- # jobs (2)
- # lsp (20)
- # membrane-term (19)
- # numerical-computing (1)
- # off-topic (8)
- # pathom (3)
- # polylith (17)
- # portal (42)
- # re-frame (7)
- # reagent (32)
- # remote-jobs (1)
- # shadow-cljs (86)
- # spacemacs (3)
- # tools-deps (52)
- # uncomplicate (1)
- # xtdb (23)
I've been doing some old AOC problems as a warmup and am confused about why my solution for Year 2015, Day 3 isn't working. https://adventofcode.com/2015/day/3
(ns aoc.2015.day-03)
(def input
(slurp "resources/2015/day_03.txt"))
(def direction->move
{\^ [1, 0]
\v [-1, 0]
\> [0, 1]
\< [0, -1]})
(def moves
(map direction->move input))
(defn part-1 [moves]
(loop [moves moves
current [0 0]
visited #{current}]
(if (seq? moves)
(let [[x y] current
[x-delta y-delta] (first moves)
next-house [(+ x x-delta) (+ y y-delta)]]
(recur (rest moves) next-house (conj visited next-house)))
(count visited))))
(part-1 moves)
This is the error I get:
; eval (root-form): (part-1 moves)
; (err) Execution error (NullPointerException) at aoc.2015.day-03/part-1 (REPL:22).
; (err) Cannot invoke "Object.getClass()" because "x" is null
When I evaluate moves
I get a seq of vecs like so:
(take 5 moves) => ([0 1] [1 0] [1 0] [-1 0] [1 0])
but I would want that to be false right? I'm confused. haha. I thought it was idiomatic to use seq?
in the if conditional on ... seqs
so what do you think of that solution (it works now btw)? I still struggle turning that whole loop/recur approach into a reduce (or better?) approach.
It’s still up! https://potetm.com/video/aoc-2018-d01.html
I happened to have recently done most of the the 2015 problems. Let me get mine real quick.
here’s mine: https://github.com/tschady/advent-of-code/blob/main/src/aoc/2015/d03.clj
I broke out part-1 into a separate function to give me the set of houses visited so then my part-2 becomes:
(defn part-2 [moves]
(let [santa-moves (take-nth 2 moves)
robo-moves (take-nth 2 (rest moves))
santa-houses-visited (houses-visited santa-moves)
robo-houses-visited (houses-visited robo-moves)]
(count (clojure.set/union santa-houses-visited robo-houses-visited))))
You can go here for my full solution to both parts: https://github.com/potetm/advent-of-code/blob/master/src/advent_2015/day_3.clj
But there are some fundamental questions you can ask yourself when trying to figure out whether you need recursion or reduction or sequence fns.
1. Am I working on a collection?
a. If yes, then you can maybe reduce or sequence fns
b. If no, then you either need loop/recur or iterate
2. Do I need to track state across members of the collection?
a. If yes, then you either need reduction or partition
b. If no, then you can use sequence fns
3. Do I need to control flow?
a. If yes, then you probably need loop/recur
b. If no, then you can use reduction
In this case, you’re working on a collection, you do need to track state, but you don’t need to control flow (because you’re just going to process the entire input collection).
The only thing you might not know is there is a function reductions
which will give you every intermediate state of a reduce operation.
I actually used reductions
for day-1 but still it didn't occur to me to use that one here. I imagine it is quite useful.
(fwiw reductions
and iterate
are extremely useful for AoC and basically useless in every other context :D)
defn part-2 [directions]
(let [current-floor (reductions + directions)]
(inc
(.indexOf current-floor -1))))
now I'm even more excited for AOC (well the first week at least before I burn out, lol) so I can get more tips like this
Honestly, I didn’t even know .indexOf
was implemented on sequences. That’s a good tip!
Yeah I thought that was nifty. So in my solution though, I am processing the whole sequence first and then checking to see where the -1
is right? Is that a lot worse than continually checking for the solution as it's processing through lazily? Does that question make sense? haha
Yeah that makes sense. The only way to know is to implement the lazy version and time it.
If you really wanna know, you give the JIT time to warm up by running in a loop: https://github.com/potetm/advent-of-code/blob/master/src/advent/util.clj#L43-L62
But for AoC, I generally take the attitude of, “If it finishes in a few seconds, it’s fine.”
Fun chat. Thanks for rubber ducking that issue with me. I felt my logic was solid so I was pulling my hair out a bit
While not as terse as some other solutions, here’s my 2015 Day 3 as well, for comparison: https://github.com/cdeszaq-org/adventofcode/blob/main/src/com/cdeszaq/adventofcode/twenty15/day3.cljs#L13-L37
Uses reductions
as well and looks to be largely the same as some others, but makes liberal use of thread macros and named functions to break up the logic.
Sadly, I won’t be able to take part this year. Grad school (MSCS program), with a major project due on the 12th and a final exam on the 17th. 😞.
Hello peeps 🙂 i was trying to re-do some problems from last year and when I try this
(time
(first
(for [x entries
y entries
:let [z (- 2020 x y)]
:when (< x y z)
:when (contains? entries z)]
(* x y z))))
it finishes in 22 ms
without first it finishes in less under 1 ms
Is the difference because the repl takes care of printing the resulting LazySeq and so it's not counted in the time
calls?
nice I was a bit confused because i actually saw the result 😄
Actually, because of chunking, you realize first 32 elements when you call first.
user=> (first (for [x (range 1000)] (do (prn x) x)))
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
0
my point is that for
might realize more than needed because of chunking.
yeah, sorry )
and the difference here between @U04V4KLKC and @U07S8JGF7 output is due to what?
@U01HY37QQUA It’s called “chunking”
ah so it's probably a different code path in for?
(chunked-seq? (range)) => false
(chunked-seq? (range 1000)) => true
there you have it
yep, the 217019-4a55b8eb
is a code to join adventofcode-clojurians
private board

so are these private leaderboards just tracking the time to complete like the main site? I don't get to them until 8-12 hours after they are posted.
It would be cool to get something that ran benchmarks for submitted solutions. I am inexperienced in benchmarking stuff so could be cool to explore as a project idea
@U9J50BY4C The really nice thing about the Clojure leaderboard isn't so much the scorekeeping -- It's that it often links to git repositories so you can compare methods used after you get done.. @U04V15CAJ did a benchmarked repo for CLJC a few years ago. It was kinda cool.
I wrote this code last year to benchmark my solutions. Not general, but may be interesting to some. https://github.com/pshapiro4broad/advent2020/blob/main/src/main.clj
$ clj -X main/-main
day1/part1 : "Elapsed time: 38.363232 msecs"
day1/part2 : "Elapsed time: 976.244442 msecs"
day2/part1 : "Elapsed time: 12.697295 msecs"
day2/part2 : "Elapsed time: 6.865864 msecs"
day3/part1 : "Elapsed time: 1.519996 msecs"
day3/part2 : "Elapsed time: 2.062161 msecs"
...
@U10B0BPJP that is a good feature. I signed up.