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
2018-12-06T00:19:41.688400Z

single pass is a very elegant solution 😉 definitely the right choice of data structure influences a good solution

2018-12-06T00:20:16.689Z

from looking at a few other folks do it in other languages, my gut tells me the clojure solutions have been the most concise

fingertoe 2018-12-06T00:21:14.689500Z

I am having fun at failing at this 😉 Got mine done with about 4 or 5 approaches, all of them mighty slow… I suspect the liberal memoizing must be a pretty good skill to adopt??

mfikes 2018-12-06T00:30:24.690800Z

For this particular problem, it is probably fair to say that the overall algorithm used can dramatically affect perf.

adammiller 2018-12-06T00:37:59.691900Z

yes, I actually got my answers with a regex/replace solution that was quite slow (but worked) but then refactored to a simple reduce that is quite fast.

fingertoe 2018-12-06T00:40:25.692900Z

Pretty good learning experience — Thanks everyone!

ClashTheBunny 2018-12-06T02:16:52.693400Z

I was interested in how you did lower-case before the set, so I benchmarked it a bit and it seems like it is significant to set twice with a lower-case inbetween:

advent-of-code-2018.day05=> (cr/with-progress-reporting (cr/bench (into #{} (map s/lower-case (into #{} (parse input)))) :verbose))
Warming up for JIT optimisations 10000000000 ...
  compilation occurred before 1 iterations
  compilation occurred before 390 iterations
  compilation occurred before 779 iterations
  compilation occurred before 1168 iterations
  compilation occurred before 1557 iterations
  compilation occurred before 1946 iterations
  compilation occurred before 2335 iterations
  compilation occurred before 2724 iterations
  compilation occurred before 4669 iterations
  compilation occurred before 5447 iterations
  compilation occurred before 5836 iterations
Estimating execution count ...
Sampling ...
Final GC...
Checking GC...
Finding outliers ...
Bootstrapping ...
Checking outlier significance
x86_64 Mac OS X 10.13.6 8 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 25.192-b12
Runtime arguments: -Dfile.encoding=UTF-8 -Xmx8g -Dclojure.compile.path=/Users/ranmason/code/advent-of-code-2017/target/classes -Dadvent-of-code.version=0.1.0-SNAPSHOT -Dclojure.debug=false
Evaluation count : 29640 in 60 samples of 494 calls.
      Execution time sample mean : 2.123692 ms
             Execution time mean : 2.124454 ms
Execution time sample std-deviation : 96.420077 µs
    Execution time std-deviation : 96.989667 µs
   Execution time lower quantile : 1.940056 ms ( 2.5%)
   Execution time upper quantile : 2.234693 ms (97.5%)
                   Overhead used : 2.083859 ns
nil
advent-of-code-2018.day05=> (cr/with-progress-reporting (cr/bench (into #{} (map s/lower-case (parse input))) :verbose))
Warming up for JIT optimisations 10000000000 ...
  compilation occurred before 154 iterations
  compilation occurred before 307 iterations
  compilation occurred before 460 iterations
  compilation occurred before 1072 iterations
Estimating execution count ...
Sampling ...
Final GC...
Checking GC...
Finding outliers ...
Bootstrapping ...
Checking outlier significance
x86_64 Mac OS X 10.13.6 8 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 25.192-b12
Runtime arguments: -Dfile.encoding=UTF-8 -Xmx8g -Dclojure.compile.path=/Users/ranmason/code/advent-of-code-2017/target/classes -Dadvent-of-code.version=0.1.0-SNAPSHOT -Dclojure.debug=false
Evaluation count : 5040 in 60 samples of 84 calls.
      Execution time sample mean : 12.258769 ms
             Execution time mean : 12.263469 ms
Execution time sample std-deviation : 437.470024 µs
    Execution time std-deviation : 443.078234 µs
   Execution time lower quantile : 11.783289 ms ( 2.5%)
   Execution time upper quantile : 13.224535 ms (97.5%)
                   Overhead used : 2.083859 ns

Found 3 outliers in 60 samples (5.0000 %)
	low-severe	 3 (5.0000 %)
 Variance from outliers : 22.2472 % Variance is moderately inflated by outliers
nil

ClashTheBunny 2018-12-06T02:27:25.694100Z

@borkdude is there a reason title-cased usernames aren't allowed? Failed to validate "-u ClashTheBunny": Username must start with letter

ClashTheBunny 2018-12-06T02:48:51.694600Z

Anybody know how to get a cljs repl in the advent-of-cljc repo?

ClashTheBunny 2018-12-06T03:39:35.695200Z

Holy moly! Switching from last and butlast to peek and pop went from

CLJ: Testing aoc.y2018.d05.clashthebunny
part-2 took 222732.26 msecs
part-1 took 8448.07 msecs
to
CLJ: Testing aoc.y2018.d05.clashthebunny
part-2 took 405.82 msecs
part-1 took 9.60 msecs

CLJS: Testing aoc.y2018.d05.clashthebunny
part-1 took 154.00 msecs
part-2 took 905.00 msecs

2018-12-06T03:43:21.695700Z

ah yeah, that makes sense

2018-12-06T03:43:53.696200Z

last & butlast say linear on the tin iirc

Average-user 2018-12-06T06:50:06.697300Z

Did anyone get a really efficient solution for day6?

Average-user 2018-12-06T06:55:38.697700Z

This is what I did, but I'm not very content with it: https://github.com/Average-user/adventofcode-clj-2018/blob/master/src/adventofcode_clj_2018/day06.clj

fellshard 2018-12-06T07:06:29.698500Z

Still plugging away, I did an off-by-one error at my boundary checks 😓

2018-12-06T07:09:43.699800Z

Haven't started yet, just brainstorming. I am expecting to need to use something like a convex hull algorithm to filter out the "infinite" regions. I might be overthinking it though.

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

I optimized for time-to-leaderboard 🙂 https://github.com/taylorwood/advent-of-code/blob/master/src/advent_of_code/2018/6.clj part 1 takes 9s and part 2 takes 1s

taylor 2018-12-06T07:18:19.702500Z

the infinite region exclusion is incomplete I think, but it didn’t matter for my inputs

borkdude 2018-12-06T07:35:45.702900Z

@clashthebunny That’s a bug in the validation probably 🙂 Welcome to fix it

borkdude 2018-12-06T07:36:47.703200Z

@clashthebunny specifically this line: https://github.com/borkdude/advent-of-cljc/blob/master/test/aoc/new.clj#L69

2018-12-06T08:01:21.703800Z

#6 was good -- what really helped me speedup was typehinting :lol:

🍿 1
fingertoe 2018-12-06T08:21:56.708700Z

So, I think my lesson from day 5 just clicked… I am using the same recursion and such as the fast solutions.. I think the crux of the slowness is that I am asking (26*2)^2 possible questions “am I a reactive combination?” instead of asking the (2*26) questions “are you a reactive combination?” Haven’t tested it yet, but woke up thinking…

erwin 2018-12-06T08:29:10.711800Z

Messed up the infinite check today (but I really had no clue what to do at first...) https://repl.it/@ekroon/AOC2018-day06

fellshard 2018-12-06T10:07:36.712500Z

Hmmm. Now that I've done it the ugly brute-force way, I wonder if there's something simpler...

fellshard 2018-12-06T10:08:27.712600Z

This is technically a discrete voronoi fill in part 1, and could probably be accomplished by a variant of Dijkstra's

borkdude 2018-12-06T10:13:51.713400Z

I was confused by the description in part 2. I thought I had to calculate also if the region was connected

borkdude 2018-12-06T10:14:05.713800Z

but that wasn’t a requirement per se

borkdude 2018-12-06T10:55:27.714100Z

Testing aoc.y2018.d06.borkdude
part-2 took 389.71 msecs
part-1 took 5011.38 msecs

borkdude 2018-12-06T10:58:31.714400Z

@mfikes there’s a warning in the build logs:

WARNING: /home/circleci/repo/cljs-test-runner-out/cljs_test_runner/gen.js:319: WARNING - incomplete alias created for namespace aoc.y2017.d07.mfikes

borkdude 2018-12-06T11:00:59.714600Z

not sure what that is about

borkdude 2018-12-06T11:03:22.714800Z

reproducable with script/test-one 2017 7 mfikes

borkdude 2018-12-06T11:27:56.715100Z

@erwinrooijakkers did you see my comment on your open PR..?

erwinrooijakkers 2018-12-06T11:36:19.717900Z

Yes thanks, the code is different though. The guard->sleep-mask holds a data structure in the :sleep-mask key like [1 2 0 …] (length 60 vector where every index holds the total minutes). In solve-1 the sorted map is sorted by (apply +) (to find the total minutes) and in solve-2 it’s sorted by (apply max) to find the maximum. Thinking about this, maybe it sorts on another key… 🙂

borkdude 2018-12-06T11:38:04.718800Z

ah indeed, I see the difference is + vs max

erwinrooijakkers 2018-12-06T11:38:31.719400Z

Maybe it also sorts on guard number, and for your input the guard number is lower than the + and in mine it is higher. I’ll look into it! 😄

erwinrooijakkers 2018-12-06T11:38:50.719600Z

After work 😉

borkdude 2018-12-06T11:39:06.719800Z

😄

ihabunek 2018-12-06T11:40:42.720400Z

user=> (> (priority aoc) (priority paid-work))
true

ihabunek 2018-12-06T11:41:07.720800Z

i solved in elixir today so no clojure solution from me 🙂

genmeblog 2018-12-06T14:00:08.724500Z

spoilers!!!

2018-12-06T14:00:46.725200Z

I haven’t had time to think about it, but I drew a boundary box around the points and assumed that anything that reaches the edge of that box would continue forever. This is probably easy to prove correct/incorrect, but I didn’ worry much about that last night.

genmeblog 2018-12-06T14:01:32.725700Z

boundary box coudn't be enough

2018-12-06T14:02:00.726300Z

Do you have a counter example?

taylor 2018-12-06T14:02:35.727100Z

visualization spoiler in reply…

taylor 2018-12-06T14:02:44.727400Z

https://i.imgur.com/ASYGGIG.png

Average-user 2018-12-06T14:03:16.728400Z

I think is enough, but I'm looking for a prove. But i think is because of manhattan distance. With euclidean distance wouldn't work

borkdude 2018-12-06T14:04:32.729700Z

beautiful

2018-12-06T14:04:33.730Z

I spent all of 30 seconds thinking about whether it was correct or not, but it seemed like a reasonable starting poiint.

taylor 2018-12-06T14:04:38.730100Z

a pretty naive approach worked for me w/r/t infinite regions, but I’m guessing there’s an input that would break it

borkdude 2018-12-06T14:05:32.730600Z

Living on the edge…

genmeblog 2018-12-06T14:11:01.732200Z

@norman I'm probably wrong... boundary box could be enough with manhattan distance

👍 1
2018-12-06T14:12:26.734Z

My intuition is there would always be a bounding box and the real question was how big that box would need to be. It surely shouldn’t have to be any larger than the distance between two points and may just be 1

2018-12-06T14:13:19.735400Z

It would be interesting to have be able to move points around in one of those visualizations to try and make a counter example

2018-12-06T14:13:44.735600Z

We

2018-12-06T14:14:19.736200Z

I’ll think about it today at work.

Average-user 2018-12-06T14:17:05.736800Z

the box should be the smallest rectangle that encloses all given points

borkdude 2018-12-06T14:18:13.737Z

rectangle?

borkdude 2018-12-06T14:20:41.737100Z

is this about part 1 btw?

borkdude 2018-12-06T14:21:01.737300Z

I wondered about part 2, if the regions should be connected. I first assumed that, but I got the wrong answer

Average-user 2018-12-06T14:24:14.737600Z

yes

taylor 2018-12-06T14:25:46.738500Z

another spoiler visualization and how I detected infinite regions in thread

taylor 2018-12-06T14:25:57.738600Z

https://i.imgur.com/IkKGgyP.png

taylor 2018-12-06T14:26:21.738900Z

here I made the infinite region coordinates darker dots than their region, and the non-infinite coords are lighter dots

taylor 2018-12-06T14:26:30.739100Z

and used lighter colors for the infinite regions

taylor 2018-12-06T14:27:21.739300Z

my approach to identifying infinite regions at first was simply finding the coordinates that were nearest the four corners of the bounding rect, which worked but isn’t “correct”

taylor 2018-12-06T14:28:33.739500Z

my second approach was to find the set of coords nearest each pixel around the edge of the bounding rect, and I think this is probably correct — at least it looks correct when visualized as opposed to my first approach

borkdude 2018-12-06T14:40:29.740700Z

I just figured if an area has at least one coordinate with [0 y], [x 0], [max-x y], or [x max-y], then it’s infinite

borkdude 2018-12-06T14:40:52.740900Z

so at least one coordinate at the edge

Björn Ebbinghaus 2018-12-06T14:51:11.741100Z

@borkdude Since you have to consider the distance to all points, it has to be a connected area.

taylor 2018-12-06T14:51:57.742Z

Yeah that’s simpler and seems just as trustworthy

borkdude 2018-12-06T14:55:04.742200Z

is this a vis of part 2 btw?

Average-user 2018-12-06T15:10:59.743500Z

@taylor I sow In the code you published that you only check for closest points to corners. I think that will not always work, you should check points closest to every point in the frame that encloses all points.

taylor 2018-12-06T15:12:05.744Z

Are you looking at the latest commit?

taylor 2018-12-06T15:14:53.745200Z

That sounds like my first approach which worked well enough to solve the problem, but my latest commit uses a different strategy

taylor 2018-12-06T15:22:56.746Z

Just part 1. Not sure if I’ll have time to do part 2

taylor 2018-12-06T15:24:05.746600Z

Yes this is part 1

Average-user 2018-12-06T15:38:14.746800Z

I'll check that out then

Average-user 2018-12-06T15:40:59.747Z

Ohh I see, so you did go for the frame approach. Very similar to what I did

benoit 2018-12-06T16:03:39.747800Z

My super slow solution 🙂 (~ 20s for each part). Just doing the naive thing of walking through all points. https://github.com/benfle/advent-of-code-2018/blob/master/day6.clj

borkdude 2018-12-06T16:06:02.749100Z

@me1740 try to use (set! *unboxed-math* :warn-on-boxed), this sped up my solution significantly

💡 1
Björn Ebbinghaus 2018-12-06T16:09:58.749700Z

1500ms/500ms [MrOerni/advent-of-code-2018/day06.clj](https://github.com/MrOerni/advent-of-code-2018/blob/master/src/advent_of_code_2018/day06.clj)

benoit 2018-12-06T16:14:16.750800Z

@borkdude Thanks, assuming you mean (set! *unchecked-math* :warn-on-boxed). I'm now at ~2.2s for part one and 317ms for part two.

borkdude 2018-12-06T16:14:37.751Z

sorry, yeah

Average-user 2018-12-06T16:17:12.751300Z

I'm now at 8s/1s

fellshard 2018-12-06T16:56:02.752Z

My 'intuition check' for it is that I believe the convex hull of all points will pass through only the infinite regions. (With a caveat that that may not quite work for manhattan distance thanks to the square corners) If you have a square canvas around those points, which by definition encompasses the convex hull of those points, then that square should also pass through only the infinite regions, and so you can sniff around at the edges of the square to find them.

borkdude 2018-12-06T16:56:58.752200Z

My check is to verify if at least one of the coordinates in an area touches the edge.

taylor 2018-12-06T16:58:57.752600Z

I should note the black regions in the image are the points that are equidistant to two or more coordinates

borkdude 2018-12-06T16:59:26.752800Z

sorry, I meant the check if an area is infinite

2018-12-06T17:09:55.753Z

With euclidian distance, let's take points A (0,0), B (100,0), and C (50, -1). (Assume more points below the x-axis that prevent C from having an infinite region in the +x, -x, or -y directions.) The minimum bounding box will have its upper edge on the x-axis. C will have many points in its region along the x-axis in the vicinity of x=50. To determine if C's region is infinite we need to consider whether it still has points on the edge of the bounding box as we extend the bounding box infinitely in the +y direction. As we do that, the hypotenuse distance from the box edge to the nearest point in the set of input points becomes dominated by the y distance, and the x distance becomes irrelevant. Consider a point directly above C, such that distance to C (dC) is defined as (dx, dy) and dB is (dx+50, dy-1). At small values of dy (i.e. close to the minimum bounding box), dB is larger than dC (meaning C has points on the box edge. However as dy approaches infinity, the hypotenuse distance (dx^2 + dy^2) becomes larger than ((dx+50)^2 + (dy-1)^2). So C's region is not infinite. However, if we translate this reasoning to manhattan distance, dx never becomes irrelevant as you expand the bounding box.

2018-12-06T17:10:18.753200Z

...continued...

2018-12-06T17:11:43.753400Z

In the manhattan case, as dy approaches infinity, since the manhattan distance is the linear sum of dx + dy instead of the squared sum, dC will never get larger than dB. The same reasoning applies on the dA side, and by symmetry on all other edges of the bounding box.

2018-12-06T17:13:29.753600Z

This isn't a proof that minimum bounding box (MBB) is sufficient in the manhattan case, but it shows that the reasoning I was using for the euclidian case is not applicable to the manhattan case. Someone good at proofs could probably turn this into a proof that MBB is sufficient for manhattan though.

benoit 2018-12-06T18:10:26.761800Z

I did a visual proof to convince me that the points on the bounding box belong to infinite areas. If you take a point and a line going through it. All the areas defined by the perpendicular bisectors with the points on one side will create areas that are infinite on the other side of this line. So if you want to close the area that includes this point you will need at least one point on the other side of this line. Now if you take a point on the bounding box and the side of the bounding box as the line, by definition the points on the bounding box have only points on one side of this line so they will all belong to areas that are infinite outside of the bounding box. That was good enough to convince me 🙂

☑️ 1
Average-user 2018-12-06T18:21:24.762100Z

I prove that the minimum rectangle that enclose all points is enough

Average-user 2018-12-06T18:21:32.762300Z

proved*

Average-user 2018-12-06T18:28:17.768400Z

Ok: If we have a set R of points that form the perimeter of the smallest rectangle that encloses all points. Then if some element (r) of R has minimum distance with some point (p) of given points set (P), then one of the neighbors of r will also have minimum distance with p. Inductively, if r has a point p as minimum distance, then there are infinite points that have p as minimum distance. If we have a point outside R, then every point between that and the closest point of R, will have the same minimum distance. Therefore it cant exist a point outside R that has minimum distance with some point in P. Without a point r that has minimum distance with the same point in P. Hope is understandable

lilactown 2018-12-06T18:29:01.768600Z

I've been stuck on yesterday's part 1 for ~24 hrs. turns out I forgot to trim whitespace :face_with_symbols_on_mouth:

☝️ 1
😡 1
Average-user 2018-12-06T18:29:46.768800Z

Had the same problem in day 5

taylor 2018-12-06T21:28:54.769200Z

@borkdude you've inspired me to try my hand at rendering a heat map for part 2, but maybe not until this weekend

👍 1
fellshard 2018-12-06T22:21:43.770600Z

Mine ran horrendously slowly compared to the times some others are getting. How do y'all usually get detailed profiling on execution beyond bench runtimes?

taylor 2018-12-06T22:28:29.771200Z

I've used https://github.com/ptaoussanis/tufte long ago, might be useful for AoC

taylor 2018-12-06T22:29:01.771900Z

(and of course there's Criterium)

borkdude 2018-12-06T22:34:35.772200Z

yeah, except that it doesn’t work on ClojureScript right now

lilactown 2018-12-06T22:41:02.773Z

so many of these later challenges make mutability feel like a real feature. funny how it in no way reflects my day job 😛

borkdude 2018-12-06T22:42:15.773600Z

@lilactown yeah, it’s very different from my daily coding as well

adammiller 2018-12-06T22:43:36.774300Z

definitely great practice for both problem solving and writing code....makes me realize I need to be doing this more often!

mattly 2018-12-06T22:52:18.774900Z

same, and yet, these are similar to actual problems I've hit in my real jobs at some point

mattly 2018-12-06T22:52:49.775500Z

on the flip side, I don't think anyone would play "advent of Scrum"

1