adventofcode

Happy Advent 2020! 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
mfikes 2018-12-11T02:30:19.328100Z

This is an interesting way to calculate the “convergence time”: https://blog.jle.im/entry/shifting-the-stars.html

2018-12-11T17:16:56.381900Z

😂 it’s…. it’s beautiful

mattly 2018-12-11T05:39:57.328900Z

eff, I had ann off-by-one in my initial pass for part 1 of day11

quoll 2018-12-11T06:33:21.331Z

I’m brute forcing part 2, which always makes me feel iffy. Maybe it’s because it’s late and I should have done this in the morning, but I’m not getting any sense of intuition that there’s a faster way (except for memoizing the power value for grid points)

baritonehands 2018-12-11T06:35:36.332Z

I just printed when the max changes, and eventually it sat at the same value for awhile

baritonehands 2018-12-11T06:35:45.332400Z

it was correct when I entered it

baritonehands 2018-12-11T06:35:57.332900Z

Didn't bother to wait until it was all done

taylor 2018-12-11T06:36:00.333Z

I’m melting my laptop while trying to come up with a way to reuse calculated regions from previous sizes

quoll 2018-12-11T06:40:26.333500Z

oh, I like that!

quoll 2018-12-11T06:41:11.334300Z

so, size 10 at x,y is the same as size 9 at x,y, with another 19 values

2018-12-11T06:43:14.336600Z

I just did brute force with shared computations too. Is it was running, I did notice that after a certain size, the larger squares always decreased the power

2018-12-11T06:43:43.337700Z

So in retrospect, I could have used that to figure out the likely answer more quickly.

taylor 2018-12-11T06:43:46.337800Z

yeah, I noticed the same when trying sizes in decreasing order

taylor 2018-12-11T06:47:59.339100Z

I’m going to start using massive EC2 instances so I can brute force all the remaining problems 🙂

Average-user 2018-12-11T06:48:15.339300Z

I limited to calculate squares of maximum size 20x20, and it worked

Average-user 2018-12-11T06:48:42.339400Z

whats EC2?

taylor 2018-12-11T06:49:43.340200Z

I just got my answer using same approach as baritonehands, way faster than my brute force solution would’ve ever reached

taylor 2018-12-11T06:50:46.340700Z

you can rent big computers from AWS

Average-user 2018-12-11T06:50:58.341200Z

How much time takes part1?

2018-12-11T06:51:33.341500Z

“Elapsed time: 2553.747123 msecs”

taylor 2018-12-11T06:52:17.341700Z

I’m getting ~350ms for part 1

taylor 2018-12-11T06:53:28.341900Z

I pre-calculate the grid into a map where the key is the X coord, and the value is a vector of the cell powers indexed by Y coord, then do calcs in a loop and use max-key to find largest

taylor 2018-12-11T06:54:31.342600Z

this problem felt way easier than the past few days’ problems, and I’m glad b/c now I can go to sleep 💤

2018-12-11T06:58:59.343600Z

I thought yesterday (stars) was much easier than today, but by far that day 9 marble was the slowest for me.

quoll 2018-12-11T07:05:55.343700Z

memoizing the power function should be similar, right?

taylor 2018-12-11T07:06:15.343900Z

yeah I think so

taylor 2018-12-11T07:06:35.344100Z

just two different ways of storing the same info in memory I guess

quoll 2018-12-11T07:09:43.344500Z

yay… divide and conquer

quoll 2018-12-11T07:10:58.344900Z

Thank you @taylor. That helped me a lot

👏 1
quoll 2018-12-11T07:17:12.347500Z

I continue with squares of 3 or less as I was. But for anything larger, if it was an odd size, I recursed on the (dec size) and then added the numbers around the bottom and right edges, and if it was even, I split it into 4, and recursed on each of the quadrants, adding the results

💡 1
quoll 2018-12-11T07:18:24.348300Z

everything is memoized, so it gets those smaller squares from earlier

quoll 2018-12-11T07:21:21.348400Z

With memoization when calculating those smaller squares, it’s like they say on TV: “Here’s one we did earlier” https://www.youtube.com/watch?v=K_zpdyBz3VM

quoll 2018-12-11T07:23:15.349200Z

part 1: 932.224412 msecs part 2: 389148.15998 msecs (6min 29sec)

quoll 2018-12-11T07:23:29.349600Z

not brilliant, but it gets me to bed! 🙂

helios 2018-12-11T08:21:06.350400Z

i'm also brute forcing it to start

helios 2018-12-11T08:21:14.350600Z

and when i'll get the right answer, i'll optimize

helios 2018-12-11T08:21:23.350900Z

(unless getting the answer takes longer than a few minutes 😄 )

fellshard 2018-12-11T08:24:55.351800Z

Memory management is vital.

borkdude 2018-12-11T08:56:45.353300Z

My CLJ solution works, but the CLJS one is crapping slow

pesterhazy 2018-12-11T09:01:08.354100Z

Brute-forcing is really slow - 8s for square size 20 (never mind 100)

pesterhazy 2018-12-11T09:02:28.354500Z

Adding up numbers is not Clojure's forte

pesterhazy 2018-12-11T09:03:08.354700Z

My terrible attempt (but I'm too impatient): https://github.com/pesterhazy/advent2018/blob/master/src/advent/puzzle11.clj#L61

borkdude 2018-12-11T10:14:12.355600Z

Added two test metadata options to advent-cljc: https://github.com/borkdude/advent-of-cljc/blob/master/README.md#tests

ihabunek 2018-12-11T11:42:47.356800Z

spoilers

ihabunek 2018-12-11T11:42:59.356900Z

One fast approach is using https://en.wikipedia.org/wiki/Summed-area_table

2
ihabunek 2018-12-11T11:43:16.357200Z

i also bruteforced the solution and later found this on reddit

borkdude 2018-12-11T12:00:31.357700Z

I have an idea how to optimize. already brought it down significantly, but need some time to generalize it

2018-12-11T12:57:25.359100Z

This is my day 11, every (except the first) square is calculated from an adjacent (overlapping) neighbour. Its not fast, but did all 300 square sizes in less than the time it took me to eat lunch 🙂 https://github.com/bloat/aoc2018/blob/master/src/net/slothrop/aoc2018/day11.clj

helios 2018-12-11T14:30:19.360300Z

@pesterhazy did you also set unchecked math when doing operations?

helios 2018-12-11T14:30:24.360500Z

i understood that it has quite a big impact

helios 2018-12-11T14:31:03.361100Z

ps: I rembered about the seldom used pmap, I think in this case can be very helpful 😄 (but my solution is still slow AF)

helios 2018-12-11T14:32:24.361500Z

now i wish i was using a desktop with a nice AMD threadripper 😆

benoit 2018-12-11T14:55:38.362400Z

Using summed-area tables (as suggested by @ihabunek) https://github.com/benfle/advent-of-code-2018/blob/master/day11.clj Got me to 8s for part two.

benoit 2018-12-11T14:59:53.365500Z

I tried first to improve the brute force approach with a dynamic programming algorithm but that was still very slow.

pesterhazy 2018-12-11T15:05:25.366100Z

@helios yeah I did, no dice

borkdude 2018-12-11T15:19:10.366500Z

I get this time now:

Testing aoc.y2018.d11.borkdude
part-2 took 75854.05 msecs
part-1 took 0.46 msecs
I’ll leave it at that

borkdude 2018-12-11T15:22:29.367200Z

The approach I took was to memoize divisions and when you need a bigger area, you cut it in parts that you already calculated

misha 2018-12-11T15:36:59.369400Z

yeah, adding rows to (dec n) for "prime" ns is slow as f

genmeblog 2018-12-11T15:37:30.370300Z

finally done day 9 part 2 in 6-7 seconds 😕

misha 2018-12-11T15:38:38.371500Z

but the "total sum stops to grow at some point" feels like a guess to me. good enough to submit an answer, but not ok for "learning purposes", unless there is a known math behind it

taylor 2018-12-11T15:48:50.371600Z

yeah I think it's dependent on the distribution of negative powers

uneman 2018-12-11T16:08:21.377900Z

https://github.com/namenu/advent-of-code-2018/blob/master/src/year2018/day11.clj#L17 I've used memoize for summarized-table which is having a closure, and now I have to reload my REPL every time when I change the binding (`grid-serial`)... 😓 Can anyone give me an advise to cache my table without reloading?

borkdude 2018-12-11T16:10:20.378800Z

@namenu when I want to refresh the memoized fn I simple evaluate the whole namespace

borkdude 2018-12-11T16:12:21.379Z

not sure what you mean actually

misha 2018-12-11T16:18:18.379400Z

"Elapsed time: 2826829.717059 msecs"
:tatatananana:

⏳ 4
uneman 2018-12-11T16:18:23.379500Z

What if I want to memoize a function like,

(def efficient-f
  (memoize (fn [x] (+ x y))))
with various y? Is it possible ?

borkdude 2018-12-11T16:22:50.379800Z

No, but you can memoize (fn foo [x y] (+ x y))

borkdude 2018-12-11T16:23:10.380Z

you have to pass down the argument that varies

uneman 2018-12-11T16:30:47.380200Z

yes, i'll have to do that. maybe I can curry out y. thanks!

borkdude 2018-12-11T16:31:05.380500Z

you can never curry out something from the right

borkdude 2018-12-11T16:31:23.380800Z

so maybe a good reason to move the serial to the first position

borkdude 2018-12-11T16:31:27.381Z

I did exactly that

borkdude 2018-12-11T16:31:43.381200Z

(although I didn’t make use of it eventually)

😅 1
2018-12-11T16:32:44.381500Z

You guys thought of it while I was testing it out. Seems to work fine if you swap the arg order and use partial.

(def memo-test 
  (memoize (fn [y x] 
             (do (Thread/sleep 1000)
                 (+ x y)))))

(def par-y (partial memo-test 10))
(par-y 5) ; => (wait 1 sec) 15
(par-y 5) ; => (no wait) 15

1
2018-12-11T17:18:21.382500Z

I know day 10 has come and gone

2018-12-11T17:18:33.382900Z

but that link @mfikes posted has haunted me: https://blog.jle.im/entry/shifting-the-stars.html

2018-12-11T17:18:47.383200Z

So here’s the solution in clojure

2018-12-11T17:18:56.383300Z

(defn centralize [pnts]
  (matrix/sub pnts
              (matrix/div (reduce matrix/add
                                  pnts)
                          (count pnts))))

(defn sum-of-dots [xs ys]
  (reduce +
          (map matrix/dot
               xs
               ys)))

(defn the-t [stars]
  (let [vs (centralize (map :vel stars))
        xs (centralize (map :pos stars))]
    (long (- (/ (sum-of-dots xs vs)
                (sum-of-dots vs vs))))))

2018-12-11T17:19:24.383500Z

(expects a list of {:pos [x y], :vel [x y]}

uneman 2018-12-11T17:32:20.383700Z

Okay, I found super interesting idea called Y combinator and switched to it. 😊 https://blog.klipse.tech/lambda/2016/08/07/pure-y-combinator-clojure.html

helios 2018-12-11T17:43:52.384200Z

@misha only 50 minutes!? 😄

ccann 2018-12-11T17:56:57.385100Z

would anyone be willing to take a look at my day 11 part 2 solution and tell me why it’s so SLOW? https://gist.github.com/ccann/fe69ba05140566e5a04855a5c96380ba

2018-12-11T17:57:49.385400Z

for the interested: https://www.twitch.tv/timpote

pesterhazy 2018-12-11T18:09:00.386200Z

Here's my Day 11: https://github.com/pesterhazy/advent2018/blob/master/src/advent/puzzle11.clj#L40

Elapsed time: 186939.868152 msecs

pesterhazy 2018-12-11T18:09:59.387400Z

I ended up pre-calculating "hblocks", all blocks of size 1x1, 2x1, 3x1, etc.. up to 100x1

misha 2018-12-11T18:11:58.389300Z

@helios :kappa: did not cache pairs, only rectangles, so "prime"-width squares calculation was killing me. did not bother to rewrite again yet.

misha 2018-12-11T18:14:57.392200Z

@pesterhazy that's what I'd do next, or may be precalculate row/col triplets. another idea is to use subtraction, rather than only addition. but that requires to think through order of calculation, so when you calc 19x19, you have not only 18x18 + row + col, but 20x20 as well, from which you ca subtract 18x18-and-change

pesterhazy 2018-12-11T18:18:30.393Z

@mfikes how long does your solution take with or without pmap?

mfikes 2018-12-11T18:19:13.394200Z

With pmap about 80 seconds, but I have a dual hexacore. I haven’t done it without that, but am letting the ClojureScript version run now.

pesterhazy 2018-12-11T18:19:14.394300Z

I'm running your code right now and my laptop it sounding like the Concorde

misha 2018-12-11T18:19:38.394500Z

future is now

borkdude 2018-12-11T18:20:35.395200Z

I have a version that does it in 76 seconds without pmap on a Macbook Pro, but it’s heavily memoized

borkdude 2018-12-11T18:21:01.395600Z

oh yours computes all solutions, that’s impressive

pesterhazy 2018-12-11T18:21:52.396400Z

the (->> (for []...) (apply max-key first)) idiom comes up quite often

pesterhazy 2018-12-11T18:23:05.398200Z

that can't be efficient but .. hm maybe (reduce #(max-key first a b)) is better

pesterhazy 2018-12-11T18:24:17.399800Z

even better would be if I didn't have to create a vector on each iteration

mfikes 2018-12-11T18:25:43.400700Z

I had a version that pre-calculated everything as vectors. It was only marginally faster for some reason.

pesterhazy 2018-12-11T18:26:20.401200Z

my hblocks version is definitely faster than brute forcing

helios 2018-12-11T18:28:33.402100Z

My pmap version just outputs "Davide, do we really need to spend the evening computing?"

1
pesterhazy 2018-12-11T19:35:28.403900Z

Once again Reddit knows the real solution: https://en.m.wikipedia.org/wiki/Summed-area_table

Average-user 2018-12-11T19:42:31.404600Z

@me1740 Uploaded a version using summed-area table

pesterhazy 2018-12-11T20:00:36.405800Z

Nice.

Average-user 2018-12-11T20:02:44.406100Z

I'm gonna try to implement my own version now

pesterhazy 2018-12-11T20:10:08.406400Z

i'd really like to see a comparison to Java

pesterhazy 2018-12-11T20:13:25.406700Z

The 8s for the Clojure version seem way too slow

pesterhazy 2018-12-11T20:13:45.407100Z

This c++ version runs in 58ms for me: https://www.reddit.com/r/adventofcode/comments/a53r6i/2018_day_11_solutions/ebjogd7/

benoit 2018-12-11T20:24:24.408400Z

Yeah numerical methods in Clojure is not my forte 🙂 I would love to see improvements on this approach.

gklijs 2018-12-11T20:43:52.410200Z

I don't even going to try porting my current java solution to java, part 2 is done in 200ms now, will probably be 20 seconds in clojure..

Average-user 2018-12-11T20:54:31.410700Z

And btw, your 8s solution takes 35s to me

Average-user 2018-12-11T20:54:59.411100Z

adventofcode-clj-2018.day11> (time (part-1))
"Elapsed time: 645.790007 msecs"
[[[243 16] 3] 31]
adventofcode-clj-2018.day11> (time (part-2))
"Elapsed time: 36696.154969 msecs"
[[[231 227] 14] 129]
This is what I managed to do so far

Average-user 2018-12-11T20:55:22.411600Z

which is about the same times that takes @me1740s solution to me

fellshard 2018-12-11T21:18:45.411700Z

Oooh, that's another good way to break it down

fellshard 2018-12-11T23:45:00.417400Z

Thinking back on my solution again, and I think you could optimize it by keeping track of the last two 'layers' only - so at size 10, you only need sizes 9 and 8.

Add: <x,y>, <x+1,y>, <x,y+1>, <x+1,y+1> in layer 9
Subtract: 3 * <x+1,y+1> in layer 8
Currently I hold onto way too many old layers, because I keep track of my unit-size squares and floor(size/2) squares on up, hence my memory management problem. (This is definitely a standard 'convolution' problem, and I can't help but wonder if there's some tools to be drawn from that world...) And now thinking on this, this is pretty much one step removed from the summed-area listed above, which uses a constant amount of memory... now I need to dig deeper!