adventofcode

2021-12-05T16:31:38.273100Z

Do we think the avent of code leaderboards time are in any way indicative of how fast people get code written at work?

nbardiuk 2021-12-05T16:36:49.273400Z

From one perspective code at work is just code, they are fast there too. But code at work is a team activity if team cannot read the code it slows down everybody

💯 1
sarcilav 2021-12-05T16:40:47.274300Z

Also the starting time doesn't help everyone, I don't think everyone stays up until midnight or wakes up at 6am (GMT+1 europe for example) to tackle the challenges

2021-12-05T16:45:03.275200Z

Last task I had at work, it took me 2days. That was from nothning to finishing the coding (day and a half), testing (1/4 day), writing documentation (1/4 day). I'm just wondering if these people that top the leaderboards would be able to code up in an an hour or so what took me a day and a half

Antonio Bibiano 2021-12-05T16:59:15.276500Z

I suspect they have a very specific setup for quickly manipulating the types of inputs you typically get in the AoC

Antonio Bibiano 2021-12-05T17:03:40.276700Z

last year I read this blogpost https://blog.vero.site/post/advent-leaderboard

peterc 2021-12-05T20:25:25.297800Z

Welcome to the world of competition coding! There are definitely some skills of competition coders that carry over: familiarity with the IDE, knowledge of the language, deep understanding of many different algorithms and data structures (and able to implement them), and perhaps most importantly, passion for coding. Speed doesn't necessarily equate with value though. In practice, we often trade speed for quality.

euccastro 2021-12-05T20:50:21.299700Z

I think this came up in clojureverse or somewhere in a similar context: https://catonmat.net/programming-competitions-work-performance

euccastro 2021-12-05T20:53:56.300200Z

maybe watch the video but don't read the article; there's a huge caveat to it: Norvig is talking about Google employees, which sets a pretty high baseline for programming performance already

fingertoe 2021-12-06T03:30:46.305700Z

1 - The leaderboard probably correlates to time zones more than anything else.. 2 - I can (and do) often get a right answer with a very incomplete program, especially with the REPL. I think the leaderboard is nice for chasing down folks github repos to see if you can learn anything from their approaches though.. It also may give some motivation to keep going..

2021-12-05T16:41:09.274800Z

It might be indicative of how fast people can write code, but it’s definitely not related to productivity/adding value/anything that other people actually care about.

☝️ 2
peterc 2021-12-05T19:57:43.296100Z

not knowing anything else, would you hire a random programmer or a random person from the leaderboard? and why?

1
2021-12-05T20:00:03.296300Z

This is a really good question. Let me think on it.

2021-12-05T21:17:46.300800Z

Ok. I don’t think you realize what you’ve done. You’re about to get a lot of opinions.

😂 1
2021-12-05T21:19:11.301Z

First, the answer to your question: Realistically, I would hire neither. That would be irresponsible. But the interesting bit of the question is: Are you closer to hiring a leaderboarder or a rando?

2021-12-05T21:19:44.301200Z

I think the answer both are equally close to being hired, but in different ways.

2021-12-05T21:21:28.301400Z

One necessity of a programmer is, well, the ability to program. Obviously a leaderboarder proves this ability. Rando might possibly be in that far-left tail that actually cannot program at all. More likely that they are somewhere close to the median, but you never know. So in this regard, the leaderboarder is ahead.

2021-12-05T21:22:49.301600Z

However, there is a non-trivial subset of programmers that are very good at talking to the computer and very bad at actually solving problems.

2021-12-05T21:25:21.301900Z

These people go by different names. I often call them “tinkerers.” I heard Bryan Cantrill refer to them “compiler people” in a talk.

2021-12-05T21:28:51.302100Z

I have found that these people usually cause far more harm than good. And they’re far more nefarious, because they are often very, very busy-looking. They hurl code, knock out cards, pull late nights, get the job done. In other words, they are extremely attractive to a certain kind of manager. That makes it extremely difficult to reasonably discuss the long term effects of their behavior.

2021-12-05T21:29:51.302800Z

The fact that someone can finish an AoC in 3:50 puts them firmly in the “might be a tinkerer” category.

2021-12-05T21:31:00.303Z

The downside risks of people in this category are so high, that it completely negates any advantage they have compared to the rando who might not be able to code at all.

solf 2021-12-05T17:23:35.280200Z

Not strongly related, but I’d be hard pressed to believe that the people on top of the leaderboard aren’t better at coding in general (this is a very vague notion) than the average programmer. The only way that would make sense, is that if those people write code at work the same way they do at competitions, which isn’t a charitable view of them.

2021-12-05T19:21:34.291500Z

I don’t think there’s any conflict between this and what I said.

2021-12-05T19:21:41.291700Z

(Not sure if you thought there was or not.)

Aleks 2021-12-05T04:59:34.248200Z

🧵Day 5 answers thread: post your answers here

peterc 2021-12-05T08:00:17.252700Z

Inspired by @nbardiuk solution.

Aleks 2021-12-05T08:03:54.253200Z

@peterc in my solution it is the same ^_^

peterc 2021-12-05T08:04:47.253400Z

Yeah I just realized that looking at your solution!

nbardiuk 2021-12-05T08:22:43.253700Z

I was very surprised how close I was to the alekszelark's

😁 1
2021-12-05T09:34:23.254800Z

My solution (no clean up, I prefer to show it raw) https://github.com/green-coder/advent-of-code/blob/master/src/aoc_2021/day_5.clj

👌 1
2021-12-05T09:37:16.255300Z

My goal was to introduce Clojure to the viewers, so I didn't try to do anything complicated (i.e. simplify the program, in fact 😄 )

2021-12-05T09:42:31.255600Z

Nice use of frequencies again

Joe 2021-12-05T10:12:11.255800Z

https://github.com/RedPenguin101/aoc2021/blob/main/clojure/src/aoc2021/day05.clj and (rather boring) https://github.com/RedPenguin101/aoc2021/blob/main/day05.md Is there a function that does a sort of take-until ? i.e. take-while but on matching the predicate it will terminate the sequence? Easy enough to write with a reduce but feels like something that might be in the standard library, or there's a way to use the standard library to do that.

Joe 2021-12-05T10:35:24.256200Z

Oooh, that step in range would've saved me some hassle, totally forgot about that.

Callum Oakley 2021-12-05T11:16:42.257600Z

most interesting part for me was figuring out how to draw the line segment in a way which works for horizontal, vertical, and diagonal, and only hits the integer points without having to do any filtering. the metric you want is the https://en.wikipedia.org/wiki/Chebyshev_distance! https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2021/05.clj

👍 6
👍🏻 1
👀 1
Callum Oakley 2021-12-05T11:19:13.258100Z

ah I see @vincent.cantin did the same thing :)

2021-12-05T12:06:50.258800Z

Ended up implementing specialized version of range which can be used to expand horizontal, vertical and diagonal lines:

(defn range* [start end]
  (cond
    (< start end)
    (range start (inc end))

    (= start end)
    (repeat start)

    :else
    (reverse (range end (inc start)))))

(defn expand [[[x1 y1] [x2 y2]]]
  (map (fn [x y] [x y]) (range* x1 x2) (range* y1 y2)))
https://github.com/rap1ds/advent-of-code-2021/blob/main/src/day5.clj

Phil Shapiro 2021-12-05T13:50:09.260300Z

day 5: https://github.com/philshap/advent2021/blob/main/src/day5.clj

tschady 2021-12-05T13:51:03.260600Z

expecting more line stuff, so I’m considering abstracting this into Line protocol. went with slopes/intercepts. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d05.clj

👍 3
Antonio Bibiano 2021-12-05T13:58:54.260900Z

this is my solution for today

Antonio Bibiano 2021-12-05T13:59:12.261100Z

Antonio Bibiano 2021-12-05T14:04:10.261600Z

I was unsure about the cond in my range* .. but then the i would have had to do some kind of conditional for straight lines so might as well put it there

Antonio Bibiano 2021-12-05T14:04:46.261800Z

if the input was a single point I would be screwed 😄

sebastian 2021-12-05T14:05:12.262Z

Not the prettiest. But it works.

babardo 2021-12-05T14:06:50.262400Z

Not so dirty today ^^ https://github.com/v-garcia/aoc_2021/blob/main/day_five.clj

tschady 2021-12-05T14:08:53.262600Z

for those doing range* type stuff, might simplify to:

(defn range* [x1 x2]
  (let [dx (compare x2 x1)]
    (range x1 (+ dx x2) dx)))

👍 8
Antonio Bibiano 2021-12-05T14:10:06.262800Z

aaaah nice, was looking for that!

nbardiuk 2021-12-05T14:10:54.263Z

I've considered it for a moment but didn't try, was waried about edge case when dx is 0

Antonio Bibiano 2021-12-05T14:11:29.263200Z

looks like it's exactly what I wanted in my case mhh maybe not (range 3 3 0) => ()

➕ 2
2021-12-05T14:26:04.265Z

https://gist.github.com/stuartstein777/73f42275324d7c06b6d3510fd70e4229 ALso couldn't think of a nice general way to get points on a diagonal line given (x1,y1), (x2, y2)

2021-12-05T14:48:30.266900Z

strange that the stats show less completions today than day 4, thought today was a LOT easier than yesterday

tschady 2021-12-05T14:55:52.267200Z

hangover effect

Antonio Bibiano 2021-12-05T14:58:42.267400Z

@allaboutthatmace1789 take until could be implemented like take-while (complement pred) coll?

tschady 2021-12-05T15:03:35.267600Z

http://weavejester.github.io/medley/medley.core.html#var-take-upto is close

2021-12-05T15:51:27.268900Z

I agree with @tws that I will probably end up pulling line-pnts to a common namespace.

2021-12-05T15:51:32.269100Z

too useful for AoC

2021-12-05T15:52:36.269300Z

The alternative to (compare x1 x2) is to (sort pnts). If your points are vectors, they will sort exactly like you would want.

2021-12-05T15:52:51.269500Z

But yeah, no way around checking for undefined slopes.

jacoelho 2021-12-05T16:04:43.269800Z

Generating the points and using a map to track count https://github.com/jacoelho/advent-of-code-clj/blob/main/src/aoc/2021/day05.clj

mchampine 2021-12-05T16:10:12.270100Z

Much easier than day 4 IMO

max minoS 2021-12-05T16:19:12.270800Z

https://github.com/maxminoS/advent-of-code/blob/main/2021/src/aoc2021/puzzle09.clj took 9 whole minutes to solve this

2021-12-05T16:19:16.271300Z

Number 1 on the leaderboard today solved both parts in 3:02!😮

😱 1
max minoS 2021-12-05T16:20:57.271500Z

nice! saw your solution and it just makes my solution more horrible

2021-12-05T16:29:11.271800Z

It probably takes me a minute to parse the question and understand what I need to do, then no way can i code it up in 2 minutes... The leaderboard times are incredible

2021-12-05T16:29:56.272Z

From start to submitting right answer to part 2 today probably took me an hour ish

max minoS 2021-12-05T16:47:06.275500Z

mine took 9 minutes to run, couple hours to write probably

max minoS 2021-12-05T16:48:22.275800Z

made the mistake of creating the map and plotting each point to the map, now i see that many people just found the frequency of the points and could get the solution

2021-12-05T16:53:00.276100Z

These threads are great, Its really helpful being able to see other peoples solutions in clojure after I finish mine. Can pick up some neat functions

➕ 2
gabo 2021-12-05T16:58:57.276300Z

my (slow) solution for today https://gist.github.com/galuque/b0a932f8b262c3b6b9f993383ae61ea5

Callum Oakley 2021-12-05T17:59:22.287700Z

re: avoiding having to deal with infinite slope You don’t have to work in terms of slope at all. To be clear I don’t think there’s anything wrong with using slope and handling the divide by zero explicitly, but here’s another way of thinking about it that avoids the infinite slope awkwardness: Given a line starting at s and finishing at f (`s` and f vectors), the line segment between them is

s + t * (f - s) for t real between 0 and 1
I like this representation for problems like this, because there’s no special case for the vertical line (unlike if you try to use y = m*x + c). Now the only awkward thing is that we want integer coordinates. (f - s) is always of the form [n 0], [0 n], [n n], [n -n] for integer n since we’re given that the line is always horizontal, vertical, or at 45deg. In every case we get integer coordinates exactly when t is k/n for some integer k between 0 and n inclusive. So we can rewrite our line segment as
s + k * (f - s) / n for k in {0, 1, ..., n}
or, if you want to expand it out
[sx + k * (fx - sx) / n, sy + k * (fy - sy) / n] for k in {0, 1, ..., n}

👏 2
Callum Oakley 2021-12-05T18:01:02.287900Z

(and it just so happens that n is the “length” of the line if you use the Chessboard Distance as I mentioned above, but that’s besides the point really)

👍 1
tschady 2021-12-05T18:39:41.289400Z

no infinity problems if you convert to polar, ha

(defn theta [[[x1 y1] [x2 y2]]]
  (Math/atan2 (- y2 y1) (- x2 x1)))

🐻‍❄️ 5
euccastro 2021-12-05T19:09:47.289900Z

my solution for today would be marginally nicer if range behaved as one would guess from the docstring

When step is equal to 0, returns an infinite sequence of
start. When start is equal to end, returns empty list.
but it turns out that if step is zero and start equals end, you get the empty list. https://github.com/euccastro/advent-of-code-2021/blob/main/day5.clj

☝️ 1
euccastro 2021-12-05T19:19:27.290900Z

@nbardiuk: great one! if you want to use more standard functions, (compare end start) is the same as your (direction start end) , and (complement diagonal?) would be the same as (comp not diagonal?)

👍 1
nbardiuk 2021-12-05T19:24:27.292100Z

compare is cool, but I was woried about edge case when 2 numbers are equal, the range function needs non zero step. Another concern was that compare does not guarantee 1 or -1 just positive or negative number. In the end I didn't try it because of those concerns

✔️ 2
Aleks 2021-12-05T19:24:29.292300Z

@euccastro not exactly, (compare end start) will return 0 if start and end are equal, whereas (direction start end) will return 1.

👍 1
Aleks 2021-12-05T19:25:28.292500Z

Also, what is wrong with complement? It is from the core. ^_^

Antonio Bibiano 2021-12-05T19:27:16.293Z

oh boy.. now I wanna know when it doesn't resturn 1 or -1 😄

2021-12-05T19:27:21.293200Z

Yeah @nbardiuk brings up a legit concern w/ compare. I didn’t say it earlier and should have, but there’s nothing in the contract w/ compare that says it will return -1 or 1.

nbardiuk 2021-12-05T19:29:10.293400Z

@antbbn I saw that for strings it returns bigger numbers https://clojuredocs.org/clojure.core/compare

2021-12-05T19:29:41.293800Z

From the Comparable docstring: > Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

2021-12-05T19:30:09.294Z

People do things like (- this that).

2021-12-05T19:30:42.294200Z

It’s not a big deal for AoC, but people should probably be aware of the general applicability.

👍 2
euccastro 2021-12-05T19:41:43.295300Z

thanks! and sorry, I should have read the whole thread before commenting at least; there was already talk about range and compare

euccastro 2021-12-05T19:47:29.295500Z

@zelark are you asking me or @nbardiuk? I do suggest using complement

nbardiuk 2021-12-05T19:48:53.295700Z

I have a silly reason, comp not is just shorter than complement 😂

🙂 1
😅 1
genmeblog 2021-12-05T20:08:11.296600Z

what a mess!

🤯 1
🤩 4
2021-12-05T20:25:11.297600Z

Wasnt aware of Clojure2d, looks cool

👍 1
genmeblog 2021-12-05T20:26:49.298100Z

(I'm the author btw)

danielgrosse 2021-12-05T20:37:00.298700Z

Nice to see I have come to a similar solution than others and not that ugly mess I did the last days. 😆

🎉 3
Sam Adams 2021-12-05T20:59:41.300400Z

Late again: https://samadams.dev/2021/12/05/advent-of-code-day-5.html

Felipe 2021-12-05T21:34:10.303300Z

after day 3 and 4, really happy with how clean mine came out https://github.com/FelipeCortez/advent-of-code/blob/master/2021/05.clj

👍 1
2021-12-05T22:31:03.303600Z

https://github.com/kfirmanty/advent-of-code-2021/blob/main/src/day5.clj - went fairly quickly, but then got wrong results for part2 and lost traction for a while but then noticed that my naive algorithm of conversion straight line -> points generates way too much points for diagonals so wrote another naive algo to generate points for diagonals 😄

Mario C. 2021-12-05T22:32:46.304200Z

Day 5. Couldn't figure out how to solve without brute forcing and generating all coordinates on the line.

(def puzzle-input
  (-> (str/split (input "day5.txt") #"\n")))

(defn coordinate [coord-str]
  (let [[x1 y1 x2 y2] (mapv read-string (re-seq #"\d+" coord-str))]
    {:x1 x1 :y1 y1
     :x2 x2 :y2 y2}))

(defn vertical-or-horizontal? [{:keys [x1 y1 x2 y2]}]
  (or (= x1 x2) (= y1 y2)))

(defn *range [a b]
  (if (> b a)
    (range a (inc b) 1)
    (range a (dec b) -1)))

(defn generate-line-coords [{:keys [x1 y1 x2 y2]}]
  (->> (cond
         (= x1 x2) [(repeat x1) (*range y1 y2)]
         (= y1 y2) [(*range x1 x2) (repeat y1)]
         :else     [(*range x1 x2) (*range y1 y2)])
       (apply mapv (fn [x y] {:x x :y y}))))

(defn overlapping-points [coordinates]
  (->> coordinates
       (mapcat generate-line-coords)
       (sort-by (juxt :x :y))
       (partition-by identity)
       (filter #(>= (count %) 2))
       (count)))

(defn part-one [puzzle-input]
  (->> (mapv coordinate puzzle-input)
       (filter vertical-or-horizontal?)
       (overlapping-points)))

(defn part-two [puzzle-input]
  (->> (mapv coordinate puzzle-input)
       (overlapping-points)))

(comment
  (part-one puzzle-input)
  (part-two puzzle-input))

Aleks 2021-12-06T04:19:46.306600Z

@euccastro oh, sorry, I didn’t parse it correctly 😊

👍 1
🙂 1
fingertoe 2021-12-05T06:47:06.249800Z

https://github.com/jreighley/aoc2021/blob/master/src/day5.clj

👍 1
R.A. Porter 2021-12-05T07:18:21.250100Z

I'm sure if I remembered my linear algebra at all, I'd have a cleverer way of getting the points on a line (the degenerate cases were easy with for comprehension). But this'll do. https://coyotesqrl.github.io/advent-of-code/2021/#/src%2Fcoyotesqrl%2F2021%2Fday5.clj

nbardiuk 2021-12-05T07:21:32.250300Z

https://github.com/nbardiuk/adventofcode/blob/master/2021/src/day05.clj

👍 2
👏 1
nbardiuk 2021-12-05T07:26:26.251200Z

I am also curious if there is a geometrical property that can help to avoid generating points

AC 2021-12-05T07:34:00.251400Z

@coyotesqrl I wrote an almost identical version of your move-fn (picking dec, inc, or identity as a 'step' function)

(defn step-fn [a b]
  (cond (> a b) dec
        (< a b) inc
        :else identity))

👍 1
Andrew Byala 2021-12-05T07:34:04.251600Z

Once again, it's not concise, but I had fun with letfn and some-fn, so this was a terrific learning experience. Looking forward to reading your solutions... tomorrow... https://github.com/abyala/advent-2021-clojure/blob/main/docs/day05.md

R.A. Porter 2021-12-05T07:38:23.252200Z

@agile-cactus I had initially been using range for the degenerate cases, but gave up on it when I went to diagonal. I just constantly forget I can call map over multiple collections.