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
Sam N 2019-12-03T00:58:55.086700Z

My day 2. Based on other solutions, I need to learn to use for a bit better, but happy overall. https://github.com/SNordlinger/advent2019/blob/master/2/clj/src/comp.clj

bentrent 2019-12-03T01:21:58.088700Z

My day AOC (up to day2) : https://repl.it/@ben_w_trent/aoc2019 Lessons learned: (for [x (range 99) y (range 99)] [x y]) Did not know about for for generating sequences 😄. I was doing some super complex combinatorics and thought that there HAD to be a better way. Glad there is

taylor 2019-12-03T02:19:56.090100Z

Also beware range is exclusive upper bound but I think the problem calls for inclusive range

dpsutton 2019-12-03T02:20:44.090800Z

day 2 was a bit simpler since there was only multiplication and addition involved. and they chose quite easy numbers to solve it

bentrent 2019-12-03T02:20:44.090900Z

Ah, cool. Well, my solution was under 99 :).

taylor 2019-12-03T02:28:33.092100Z

Same 😌

dpsutton 2019-12-03T03:06:17.092600Z

part 2 is a particularly nice way to add core.logic as well

2019-12-03T03:25:03.093500Z

order of operations tripped me up at the end

2019-12-03T03:25:09.093700Z

#lisplyfe

2019-12-03T03:25:30.094300Z

I’ve brain-dumped all order of operations rules

mnespor 2019-12-03T03:25:55.094400Z

(ns advent.day02.day02
  (:require [clojure.math.combinatorics :as combo]))

(def blah (combo/selections (range 100) 2))

erwinrooijakkers 2019-12-03T08:55:05.119300Z

Gets only half the combinations 😉

mnespor 2019-12-03T15:47:36.140600Z

It gets 'em all, doesn't it?

advent.day02.day02> (combo/selections (range 3) 2)
((0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2)

kenj 2019-12-03T03:51:46.096100Z

one thing that came up in my brute force search was it wasn’t clear what the best way to break from the search was. I ended up using some, but is there a better way to basically do:

for i in coll:
  if i == search_item:
    return i

kenj 2019-12-03T03:52:07.096400Z

thus avoiding searching the rest of the collection?

kenj 2019-12-03T03:52:46.096900Z

I’ve read the docs a bunch of times and :when and :while still confuse me for for

erwinrooijakkers 2019-12-03T08:55:32.119500Z

I did like this: https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2019/day2.clj#L37

erwinrooijakkers 2019-12-03T08:56:02.119800Z

for is lazy so when you get the first it terminates early

kenj 2019-12-03T19:38:46.151Z

I thought since sequences are lazy, they might "chunk"? After thinking about it, I think that might be true even for my some usage. The only way to avoid chunking is using reduce/`reduced`, or maybe bypass chunking with lazy-seq?

erwinrooijakkers 2019-12-03T22:23:37.151300Z

Why would chunking be a problem?

kenj 2019-12-04T02:49:42.161300Z

Because chunking would eval until 32 possible matches are found, or the source coll is exhausted, then first returns to first one. This would be the opposite of termination at the first found.

tws 2019-12-03T04:15:38.097200Z

reduced can exit early from a reduction

fellshard 2019-12-03T04:31:37.097900Z

Ooh, good idea re: core.logic. I'll have to try it, definitely cleaner than for ...

👍 1
lilactown 2019-12-03T04:39:13.098500Z

@risinglight one thing you can take advantage of is the fact that for is lazy

lilactown 2019-12-03T04:39:39.099400Z

So instead of “breaking” from a for loop, you instead can read each element from the sequence it produces until you get your result

rutledgepaulv 2019-12-03T04:40:38.100500Z

usually if i want to break i’d reach for loop/recur, or as mentioned reduce/reduced

lilactown 2019-12-03T04:41:20.101600Z

ugh I can’t remove the preview on mobile

lilactown 2019-12-03T04:43:53.102500Z

github .com/Lokeh/advent-2019/blob/master/day2.org#part-2 (pasting it again so that Slack won’t show the rich preview... which I can’t delete on mobile)

lilactown 2019-12-03T04:47:18.103900Z

reduced is also fine but if your data can be reasonably done using for, then take-while is usually a better answer than turning to reduce and reduced

kenj 2019-12-03T04:54:12.109Z

take-while seems like the wrong thing for what is essentially a find of a single item. some I guess is good enough, I was just annoyed I had to modify the pred to rerun the found value https://github.com/KennyMonster/aoc_2019/blob/737ec52c74fea4dc42f856b6b69cb73588e016ba/src/day_2.clj#L66

kenj 2019-12-03T04:55:50.110200Z

Would be nice to have the predicate just be a predicate in this particular case

mchampine 2019-12-03T05:00:10.110400Z

And… we’re off!

misha 2019-12-03T06:20:39.111Z

it is lazy infinite positive quarter of a xy plane. Sweet, but yeah, ranges are known, so for is more readable and sufficient here

misha 2019-12-03T06:24:24.113400Z

@alex.lee.jackson aoc is not a good way to learn clojure. Maybe the first puzzle of each day is, but most of the 2nd ones steer you towards the loop recur pretty consistently, if you don't want to wait for results forever.

uneman 2019-12-03T08:24:35.117600Z

thanks for the explaination! 🙂

misha 2019-12-03T08:36:55.117900Z

np. but if reduce fits nicely (whatever that means in the moment) - use it!

fellshard 2019-12-03T08:40:17.119100Z

For me, depends on how much state I'm juggling. Too much and I'll reify it as a reduce fn.

misha 2019-12-03T08:56:26.120100Z

wow, I tend to loop too much coupled state instead. (in context of aoc. in another context: too much coupled state usually means you have issues somewhere else)

😉 1
genmeblog 2019-12-03T13:42:37.129400Z

I checked my last years code and never used any loop. I used recur sometimes, once custom type to speed the things up. But never needed to use loop/recur. I suppose that what's crucial is a selection of best matching data structure to the problem and to the Clojure.

misha 2019-12-03T06:27:21.113500Z

(get [] 1)
=> nil
(nth [] 1)
Execution error (IndexOutOfBoundsException) 
([] 1)
Execution error (IndexOutOfBoundsException) 

rjray 2019-12-03T06:31:00.113900Z

Day 3 done. This has escalated.

misha 2019-12-03T06:31:23.114100Z

just a bit

misha 2019-12-03T06:33:08.115Z

can't even hear CPU fan noises on take-while :kappa:

👍 1
Average-user 2019-12-03T06:52:03.115300Z

I wasn't sure if those values where necessarily bounded. But yeah.

uneman 2019-12-03T07:16:45.115600Z

loop recur can be decomplected into state & reducing function. I'm curious if you prefer loop recur over a sequential approach. or is it only desireable on 2nd ones for performance reason?

mchampine 2019-12-03T07:29:51.116500Z

Done. Whew. Thank goodness part2 was a small increment if you chose the right grid representation.

yenda 2019-12-03T12:10:04.124900Z

which one did you chose? I went with a map of sets and changed it to a map of map for the part2 which was a small change

mchampine 2019-12-03T16:02:28.143800Z

I used a simple list of x,y pairs. Once I had the intersections I could just drop everything after that point and the remaining points were the path length.

mchampine 2019-12-03T16:12:24.148100Z

That is, for each intersection point search the full path (ordered list of points) for it. All the points before it are the length of the path to get there. The shortest path wins.

misha 2019-12-03T07:34:11.116600Z

it ends up being the same amount of eager code, same early termination, a bunch of state "variables", but reduce is 2 things, 1 of which now has a very hairy fn signature and loads of destructuring

👍 1
misha 2019-12-03T07:41:22.117200Z

besides, most reduces are implemented via loop recur under the hood, so might as well just skip the middle man (especially in context of average aoc part 2 puzzle)

fellshard 2019-12-03T08:39:03.118600Z

https://github.com/armstnp/advent-of-code-2019/blob/master/src/advent_of_code_2019/day3.clj http://quil.info/sketches/show/3045c99a9e8afbecc5e229977f6a828c0747e3073eb54b45111cd5e3717aa7db Using line segments instead of points made for easier viz, but harder solving. Heh.

👍 1
fellshard 2019-12-03T08:39:31.119Z

Whoops, left my reminder comment at the top

mpcjanssen 2019-12-03T09:31:00.121100Z

part2 was actually easier today

mpcjanssen 2019-12-03T09:35:35.121900Z

Probably because I am storing separate points on the line

misha 2019-12-03T09:49:33.122100Z

:when (not (and (= (first segment-1) [0 0])
                (= (first segment-2) [0 0])))]
can be just (disj [0 0]) from all collisions 2 lines below

misha 2019-12-03T09:51:55.122400Z

besides, how do you know that [0 0] is only first in segment? and that lines do not go through [0 0] ever again

fellshard 2019-12-03T10:12:48.122600Z

The problem statement explicitly says to ignore it. Otherwise, definitely just an assumption. 🙂

uosl 2019-12-03T10:27:45.123800Z

My solution for today's part2 is sloow: "Elapsed time: 7919.040046 msecs" I'm getting flashbacks from last year when my part2 solutions were too inefficient to compute in time 😓

misha 2019-12-03T10:31:01.123900Z

yeah, it says ignore [0 0], but I mean, you assume it appears only on segment start, and no segment ends at [0 0]

misha 2019-12-03T10:32:18.124100Z

so segment [[0 -2] [0 -1] [0 0]] might leak [0 0] into collisions set

misha 2019-12-03T11:06:52.124600Z

stick transient in there :kappa:

yenda 2019-12-03T12:13:46.125400Z

or rather rethink your datastructures

yenda 2019-12-03T12:15:26.126100Z

mine takes 75ms with maps

yenda 2019-12-03T12:17:38.127200Z

did you go with some lists/vectors?

uosl 2019-12-03T12:25:13.127900Z

yes, I went with a vector of all the coordinates for a line, then turned it into a set for running intersection

👍 1
mpcjanssen 2019-12-03T12:28:03.128300Z

same here and same perf

uosl 2019-12-03T12:47:34.129100Z

Would you mind sharing your solution? I'm curious how it looks with maps.

mpcjanssen 2019-12-03T14:18:07.132Z

I am doing everything on my phone this year, would be much more difficult with other other languages. But works great with clojure and jupyter

mpcjanssen 2019-12-03T14:19:41.133600Z

Interesting (positive) side effects, I make more granular functions and think more before starting to type.

😍 1
genmeblog 2019-12-03T14:20:23.134Z

Hardcore coding 🙂

mpcjanssen 2019-12-03T14:22:10.134300Z

Holiday time waster 🙂

mpcjanssen 2019-12-03T14:24:10.136100Z

Let's see how long I can keep it up

genmeblog 2019-12-03T14:24:13.136200Z

Writing anything on the phone (even simple messages) is so inconvenient that I can't even imagine editing the code.

mpcjanssen 2019-12-03T14:25:00.137200Z

The trick is to type less (so think first) and a good soft keyboard helps.

genmeblog 2019-12-03T14:25:29.137800Z

For sure. The idea to think more before typing is always beneficial

tws 2019-12-03T14:45:11.139100Z

2019 day 3 is similar to 2016 day 1. Just absolute moves instead of relative turns. I wound up putting that code into a aoc.grid library.

fingertoe 2019-12-03T15:17:23.140500Z

Got the first part done — running 500-700 ms. Traded the leaderboard points for sleep. Will finish part 2 later today..

fellshard 2019-12-03T15:48:16.140800Z

It might; one of the keys to AoC is figuring out which assumptions you can make safely, sometimes the hard way. Sometimes your solution only works for your input, just because it doesn't challenge that particular assumption. The primary reason I expect there's no [0 0] collision is that it would be a 'trivial solution' to part 1, too easily accidentally guessed for a quick leaderboard time, even if by a fraction of people; that's just not how he operates.

pesterhazy 2019-12-03T16:52:06.148300Z

haha, already planning ahead for 2020! 🙂

Mario C. 2019-12-03T19:00:24.150900Z

Just finished day 3. This one was tedious. Gonna look at other solutions. I modeled my solution based on lines (two points) and intersections (points). Perhaps it may have been easier to build a grid.

erwinrooijakkers 2019-12-03T22:34:01.153700Z

https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2019/day3.clj not a masterpiece - don’t see how to improve the clojure or the performance. NOTE: peek instead of last to get last element of a vector led to running twice as fast.

erwinrooijakkers 2019-12-04T09:16:43.189400Z

Oh I did not

erwinrooijakkers 2019-12-04T09:16:49.189600Z

I will try that 🙂 hehe

erwinrooijakkers 2019-12-04T09:16:53.189800Z

Didn’t think about that

erwinrooijakkers 2019-12-04T11:02:27.192200Z

Initial: “Elapsed time: 1323.049568 msecs” With clojure.set/intersection “Elapsed time: 861.311297 msecs” 😉

erwinrooijakkers 2019-12-04T11:02:55.192500Z

For part 1

genmeblog 2019-12-03T23:01:33.153900Z

Nice solution. But I see you were lucky. Intersections can have negative coordinates and you should sum absolute values rather than filtering negative results (see manhattan distance definition).

erwinrooijakkers 2019-12-03T23:05:25.154100Z

Aha so sum absolute values and remove zero?

erwinrooijakkers 2019-12-03T23:05:29.154300Z

Thanks 🙂

tws 2019-12-03T23:25:13.155Z

did you try using clojure.set/intersection and measure the performance? curious.

1