adventofcode

Chase 2021-11-30T15:45:50.025800Z

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

Chase 2021-11-30T15:46:00.025900Z

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

Chase 2021-11-30T15:46:26.026100Z

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                                    

Chase 2021-11-30T15:47:56.026300Z

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

Chase 2021-11-30T15:48:30.026600Z

So I'm not sure where this whole null thing is coming from. Any tips?

2021-11-30T16:00:11.026900Z

is there a dangling newline in input or something?

Chase 2021-11-30T16:01:13.027100Z

I was thinking something like that could be happening but (last moves) gives me [0 -1]

2021-11-30T16:01:51.027300Z

(remove some? input)

2021-11-30T16:02:24.027500Z

alternatively, (remove some? moves)

Chase 2021-11-30T16:03:00.027700Z

that is giving me an empty seq...

2021-11-30T16:04:08.027900Z

oh lol

2021-11-30T16:05:42.028200Z

(seq? (rest '([1 0]))) => ?

Chase 2021-11-30T16:08:07.028500Z

hmmm, so that is evaluating to true huh

Chase 2021-11-30T16:08:53.028700Z

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

2021-11-30T16:10:51.028900Z

You’re looking for seq I think.

Chase 2021-11-30T16:10:52.029100Z

oh wait... it's idiomatic to use seq not seq? huh? lol. D'oh!

2021-11-30T16:10:55.029300Z

😄

Chase 2021-11-30T16:11:10.029500Z

This is what I get for having to leave clojure for a few months

Chase 2021-11-30T16:12:24.029700Z

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.

Chase 2021-11-30T16:12:40.029900Z

I remember a year where you did some awesome videos going through that process

2021-11-30T16:18:03.030100Z

It’s still up! https://potetm.com/video/aoc-2018-d01.html

2021-11-30T16:18:27.030300Z

I happened to have recently done most of the the 2015 problems. Let me get mine real quick.

2021-11-30T16:19:06.030500Z

aaah yeah

2021-11-30T16:20:45.030700Z

You want me to just post my solution here?

Chase 2021-11-30T16:21:26.030900Z

Yeah, that would be great. Just for part 1 please. I'm about to tackle part-2.

2021-11-30T16:22:28.031100Z

Hmmm… my part-1 basically covers part 2

2021-11-30T16:22:42.031300Z

Alternatively, I can give you some kind of hint if you prefer.

2021-11-30T16:24:26.031500Z

why not both?

Chase 2021-11-30T16:24:49.031700Z

Let's do it. I already finished part-2 anyways.

tschady 2021-11-30T16:25:10.031900Z

here’s mine: https://github.com/tschady/advent-of-code/blob/main/src/aoc/2015/d03.clj

Chase 2021-11-30T16:25:45.032200Z

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

2021-11-30T16:26:16.032400Z

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

tschady 2021-11-30T16:27:06.032800Z

same idea

2021-11-30T16:27:32.033Z

But there are some fundamental questions you can ask yourself when trying to figure out whether you need recursion or reduction or sequence fns.

2021-11-30T16:30:36.033200Z

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

2021-11-30T16:31:10.033400Z

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

2021-11-30T16:31:27.033600Z

So you know immediately that reduction is applicable.

Chase 2021-11-30T16:31:35.033800Z

I like this!

2021-11-30T16:31:51.034Z

The only thing you might not know is there is a function reductions which will give you every intermediate state of a reduce operation.

Chase 2021-11-30T16:32:47.034200Z

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.

2021-11-30T16:33:02.034400Z

(fwiw reductions and iterate are extremely useful for AoC and basically useless in every other context :D)

Chase 2021-11-30T16:34:15.034600Z

defn part-2 [directions]                                                                        
  (let [current-floor (reductions + directions)]                                                 
    (inc                                                                                         
     (.indexOf current-floor -1))))                                                              

Chase 2021-11-30T16:34:23.034800Z

it definitely made that one easy

Chase 2021-11-30T16:34:57.035Z

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

2021-11-30T16:35:30.035200Z

😄 I’m not sure I plan on keeping up at all this year.

2021-11-30T16:35:49.035400Z

Honestly, I didn’t even know .indexOf was implemented on sequences. That’s a good tip!

Chase 2021-11-30T16:38:16.035600Z

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

2021-11-30T16:39:40.036Z

Yeah that makes sense. The only way to know is to implement the lazy version and time it.

2021-11-30T16:40:21.036200Z

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

2021-11-30T16:41:15.036600Z

But for AoC, I generally take the attitude of, “If it finishes in a few seconds, it’s fine.”

Chase 2021-11-30T16:42:15.036800Z

Yep. haha. The repl returns the answer immediately so that's good for me.

Chase 2021-11-30T16:43:27.037Z

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

2021-11-30T16:44:25.037200Z

Yeah man, feel free to reach out again! It was fun for me as well.

cdeszaq 2021-11-30T19:17:38.039600Z

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.

2021-11-30T19:34:56.040900Z

#nomorethreaders #nomorenames

rjray 2021-11-30T18:26:23.038400Z

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. 😞.

tschady 2021-11-30T18:52:40.039300Z

in my day, that would guarantee i finish AoC 😬

tschady 2021-11-30T18:53:21.039500Z

mega nerd snipe

pez 2021-11-30T19:33:20.040700Z

I like how this channel awakens to the occasion.

😁 1
nbardiuk 2021-11-30T19:34:57.041100Z

set the channel topic: Happy Advent 2021! Please put answers in the pinned threads or create one if it does not exist yet. | https://github.com/adventofcode-clojurians/adventofcode-clojurians | Join the private leaderboard with code 217019-4a55b8eb

Antonio Bibiano 2021-11-30T19:41:40.042Z

Hello peeps 🙂 i was trying to re-do some problems from last year and when I try this

Antonio Bibiano 2021-11-30T19:41:48.042300Z

(time
 (first
  (for [x entries
        y entries
        :let [z (- 2020 x y)]
        :when (< x y z)
        :when (contains? entries z)]
    (* x y z))))

Antonio Bibiano 2021-11-30T19:42:02.042700Z

it finishes in 22 ms

Antonio Bibiano 2021-11-30T19:42:14.043Z

without first it finishes in less under 1 ms

Antonio Bibiano 2021-11-30T19:43:51.044800Z

Is the difference because the repl takes care of printing the resulting LazySeq and so it's not counted in the time calls?

2021-11-30T19:45:42.045900Z

Sort of.

2021-11-30T19:45:55.046100Z

When you call first you realize the first element of the sequence.

2021-11-30T19:46:13.046300Z

When you do not call first you realize none of the sequence.

✅ 1
Antonio Bibiano 2021-11-30T20:01:32.047100Z

nice I was a bit confused because i actually saw the result 😄

Kirill Chernyshov 2021-12-01T09:41:29.066300Z

Actually, because of chunking, you realize first 32 elements when you call first.

2021-12-01T14:51:24.077Z

Actually, no.

2021-12-01T14:52:16.077200Z

for returns a LazySeq which isn’t chunked.

Kirill Chernyshov 2021-12-01T16:13:32.078100Z

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

2021-12-01T16:57:15.079100Z

(first
    (for [i (range)]
      (do (prn i)
          (inc i))))
0
=> 1

Kirill Chernyshov 2021-12-01T17:08:11.080100Z

my point is that for might realize more than needed because of chunking.

2021-12-01T17:09:28.080500Z

You did not say, “might.”

Kirill Chernyshov 2021-12-01T17:11:12.080700Z

yeah, sorry )

Antonio Bibiano 2021-12-01T19:05:09.084100Z

and the difference here between @delaguardo and @potetm output is due to what?

2021-12-01T19:10:59.085Z

@antbbn It’s called “chunking”

Antonio Bibiano 2021-12-01T19:15:57.085400Z

ah so it's probably a different code path in for?

Antonio Bibiano 2021-12-01T19:22:58.085800Z

(chunked-seq? (range)) => false
(chunked-seq? (range 1000)) => true

Antonio Bibiano 2021-12-01T19:23:22.086100Z

there you have it

2021-12-01T19:45:33.087600Z

right

2021-11-30T19:44:01.045200Z

@nbardiuk Is the leaderboard not adventofcode-clojurians?

nbardiuk 2021-11-30T19:44:45.045300Z

I've just bumped the year 😅

2021-11-30T19:45:06.045500Z

ah gotcha

nbardiuk 2021-11-30T19:45:16.045700Z

I think that code references adventofcode-clojurians, let me check

nbardiuk 2021-11-30T19:46:53.046500Z

yep, the 217019-4a55b8eb is a code to join adventofcode-clojurians private board

👍 3
1
Chase 2021-11-30T20:53:05.047500Z

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.

2021-11-30T20:55:19.047700Z

yeah

Chase 2021-11-30T20:56:57.048Z

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

fingertoe 2021-11-30T21:58:26.048200Z

@chase-lambert 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.. @borkdude did a benchmarked repo for CLJC a few years ago. It was kinda cool.

Phil Shapiro 2021-11-30T22:25:17.048400Z

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"
...

Chase 2021-11-30T23:04:55.048800Z

@fingertoe that is a good feature. I signed up.

tschady 2021-12-01T02:19:55.049600Z

I put my answers in tests then use a test runner that profiles.