Fork me on GitHub
#adventofcode
<
2020-12-03
>
st3fan01:12:21

In anticipation of another int computer showing up I rewrite my Python solution from last year in Clojure

st3fan01:12:44

I’m kind of surprised that I am starting to get a feeling for this style of programming

st3fan01:12:57

Anyone interested in taking a peek? It is Day 2 of 2019

Vincent Cantin03:12:26

I just saw that there is a leaderboard code for this year in the topic: 217019-4a55b8eb

solf04:12:25

Any libraries you usually use for AoC, besides combinatorics?

Vincent Cantin04:12:55

priority-map

👌 6
Vincent Cantin05:12:00

this one might become handy in some situation too: https://github.com/clojure/core.logic

fingertoe06:12:29

It’s always nice when you solve the first problem adaptively enough that the second problem just works.

3
mchampine06:12:49

Agreed. Mine didn’t “just work” but with a small tweak my part2 function also solved part 1 so I could toss out the first version. I’m ok with that. 🙂. 8 lines total! (not that they’re nice to look at..)

3
nbardiuk06:12:26

my solution for part 1 was not flexible enough to support variable vertical step, had to refactor first

mchampine07:12:01

Same. I actually started with a more general solution that would have covered both parts, then ‘realized’ it was wasted effort for the first one. My simpler first version + tweak for part 2 was still much less work than the fully general solution I abandoned.

Vincent Cantin07:12:27

> When in doubt, fork your snippets.

👍 3
fingertoe06:12:22

@dromar56 I usually try to do it without libs.. Most of the time you don’t need them..

3
👍 3
solf06:12:36

None of them needs librairies, it's only if you're trying to go for speed

fingertoe06:12:40

I do tend to create a util namespace as I go and put a lot of code I am likely to re-use there-- Usually as you go, there is a lot of backtracking, and its handy to re-use the stuff you are going to re-use frequently..

plexus06:12:08

Recording of the live stream is available on http://youtube.com/c/LambdaIsland

👍 3
plexus06:12:22

look for past live streams or wait until I re-upload a full quality version

Vincent Cantin07:12:51

I found myself wasting a lot of time reading the problem’s text.

erwinrooijakkers07:12:07

Nice. Did not know of take-nth

alekszelark09:12:52

haha, mine is very similar

kenj07:12:04

Anyone have any suggestions on how I can make my (reduce) more readable? I feel like if I came back even a week from now and read the reduce there, it would take me awhile. At the same time, reducing while updating multiple variables seems like a fairly common thing (at least something I do in Python a lot) and I’m wondering if there’s a better way.

👍 3
Vincent Cantin07:12:00

a loop / recur has similar effect as a reduce, with less destructuring

erwinrooijakkers07:12:55

I’ll take a look, one first suggestion is using #{\#} instead of #(= \# %) . See clojure-style-guide: https://github.com/bbatsov/clojure-style-guide#set-as-predicate

erwinrooijakkers07:12:13

;; good
(remove #{1} [0 1 2 3 4 5])

;; bad
(remove #(= % 1) [0 1 2 3 4 5])

kenj08:12:18

Thanks for the advice! I rewrote using loop and it’s cleaner IMO, though a bit longer

(defn path [dx dy data]
  (loop [result-vec []
         row-index  0
         data       (take-nth dy data)]
    (if (seq data)
      (recur
        (conj result-vec (nth (cycle (first data)) row-index))
        (+ row-index dx)
        (rest data))
      result-vec)))
Also thanks for the style guide link Erwin, I updated to use a set predicate as well.

kenj08:12:24

Re drop 1 vs rest, I thought drop 1 conveyed intentionality a bit more… like for whatever reason this problem doesn’t care about the tree that may or may not exist at your starting point, so drop it :man-shrugging:

erwinrooijakkers08:12:18

Another way is like this:

(defn path [dx dy data]
  (map (fn [row row-index] (nth (cycle row) row-index))
       (take-nth dy data)
       (iterate (partial + dx) 0)))

erwinrooijakkers08:12:13

So use map with two colls, where first coll has the rows, and second coll is lazy seq of x-indices

kenj08:12:21

ohhhh that’s clever!

kenj08:12:31

very concise while still being understandable

erwinrooijakkers07:12:20

I was looking for a take-while that does not return a lazy sequence of the original value up to (pred item), but a lazy sequence of the results of (pred item) . So not

(take-while pos? [2 3 -1]) ;; => (2 3)
but:
(*** pos? [2 3 -1]) ;; => (true true)
does this exist? I implemented a keep-while by modifing take-while to do just that, but maybe something exists already

plexus07:12:38

(comp (partial take-while identity) map)

👍 3
erwinrooijakkers09:12:46

It does go up to two times over the collection this way

erwinrooijakkers09:12:29

map and then take-while, I hoped for a solution that goes over it once

plexus10:12:16

they're lazy sequences though, sure you'll realize at least a chunk but it won't necessarily map over the whole collection. If you really want to do it single pass then I guess transducers are the way to go (comp (map your-fn) (take-while identity))

erwinrooijakkers10:12:13

true 🙂 thanks!

Vincent Cantin07:12:18

Cursive users be like “WHAAAAAAAT????!!!!” (time in the video 21:37~22:37) https://youtu.be/wXVDfzxeZ-o?t=1297

plexus07:12:59

ed(1) users be like, pfff no sweat

😄 9
vim 3
erwinrooijakkers08:12:13

haha impressive 🙂

erwinrooijakkers08:12:22

I use multiple cursors for those

plexus08:12:56

yeah I went through an mc phase but don't really use them any more. In the past I would have used emacs macros for these.

erwinrooijakkers08:12:19

bit more archaic

erwinrooijakkers08:12:37

regex has more flair

plexus08:12:58

if only emacs regexes weren't so terrible

erwinrooijakkers08:12:05

why did you stop using mc?

plexus08:12:27

not sure it was really a conscious choice. Might have happened when I switched to vim-style bindings

pez20:12:33

VS Code + Calva Paredit.

pez20:12:54

Unfortunately I haven’t had the focused time I need to make Paredit multi cursor. I miss it every day.

Vincent Cantin08:12:33

no named function --> no problem choosing and learning the names

plexus08:12:16

nice and compact!

nbardiuk08:12:29

https://github.com/nbardiuk/adventofcode/blob/master/2020/src/day03.clj - inetersting how part1 is just a smaller example for part2

👏 3
plexus08:12:19

interesting! I like how you make a separate sequence of xs and ys and then use multi-arity map!

nbardiuk08:12:33

I had to be careful to keep one of the sequences finite 😁

alekszelark08:12:03

Here is my solution, firstly I used cycle , but it’s a bit slow, so I replaced it with mod . https://github.com/zelark/AoC-2020/blob/master/src/zelark/aoc_2020/day_03.clj

Stuart09:12:12

I tried to solve day 3, I got both parts solved with a rubbish solution here

(let [input (->> (slurp "input.txt")
                 (str/split-lines))]
  (loop [x 0
         y 0
         trees 0]
    (if (>= y (count input))
      trees
      (let [cur (nth (nth input y) x)]
        (if (= cur \#)
          (recur (mod (+ 1 x) 31) (+ 2 y) (inc trees))
          (recur (mod (+ 1 x) 31) (+ 2 y) trees))))))
But then I tried to rewrite it using iterate, but I'm having two issues.
(defn is-tree [i x _]
  (= \# (nth i (mod x 31))))

(let [input (->> (slurp "input.txt")
                 (str/split-lines))
      x-step 7
      y-step 1]
  (->> (take-nth y-step input)
       (map is-tree input (iterate #(+ x-step %) 0))
       (filter true?)
       (count)))
1. Why is is-tree wanting 3 parameters here? I thought it would want 2 inputs, line from input and value from my iterate 2. it breaks when y is 2. I should get 30 on my input but I get 32 It works for (1,1), (3,1), (5,1), (7,1) but not (1, 2)

genmeblog09:12:59

[i x _] <--- you have defined 3 parameters (`_` is also a name for parameter)

Stuart09:12:22

yeah, if i remove that parameter I get an error that I'm passing wrong number of parameters.

genmeblog09:12:02

Ok, I see, threading last adds another third sequence to your map.

genmeblog09:12:29

sou you have: 1. input 2. iterate... 3. take-nth... as a thrid

genmeblog09:12:44

just remove input

Stuart09:12:45

oh yeah! of course! Thanks

genmeblog10:12:00

And this should fix the second problem I suppose

Stuart10:12:01

yes, it did 😄 Thanks for your help!

Stuart10:12:28

sometimes you stare at code and dont see a problem, then someone else spots it in a second!

genmeblog10:12:18

Yeah, that's common 🙂

misha11:12:58

(defn trees [lines [dx dy]]
  (let [width (->> lines first count)
        nextx (fn [x] (mod (+ x dx) width))]
    (->> (map get
           (take-nth dy lines)
           (iterate nextx 0))
      (keep #{\#})
      (count))))

👍 9
genmeblog11:12:02

cool, concise

benoit12:12:49

Hi everyone. A little late on the advent of code this year.

benoit12:12:11

My solution for day3. https://github.com/benfle/advent-of-code-2020/blob/main/day3.clj I went for readable code (as opposed to concise).

pez12:12:20

Not sure what you peeps have agreed upon before I joined, but I would like if we could post our solutions in threads. So, a post saying things like “here’s my solution for day X”, but then the code/description is in a reply. But if that’s not something others would want too, I’m fine with not opening this channel until I have my own solution.

👍 9
Vincent Cantin14:12:19

That's a great suggestion. I will abide.

misha12:12:23

Each day at least one solution will be posted out in the open by somebody who did not get the memo/does not care/does not think it matters/forgot/mis-clicked/etc. It is hard to coordinate 300+ people without moderation and ban-hammer (like in reddit thread). So I just don't read the channel until I stuck or have a solution. And when I do, and want to see how to improve it – browsing all the threads often becomes tiresome. On the other hand, in a week or so solutions will be too large to be spoilers at a glance, so meh ¯\(ツ)

👍 3
plexus13:12:55

I do think it's good etiquette to not just post solutions directly as code in the chat. If you just consistently remind people in a friendly way then most people will have gotten the message within a day or two. That way people can also edit their post to hide the spoiler. A hint in the channel topic would also be good, though I'm aware that far from everyone actually reads that.

plexus13:12:36

but also yes, if you really don't want to be spoilt then it's probably best to avoid this place until you've done the puzzle. Sometimes it's just a matter of discovering the right type of data structure or something like that, where it's not so much seeing the code but just seeing people talk about what they used to solve it.

misha13:12:04

I agree with you on "good etiquette", but still forecast "at least one open solution per day", now with additional ignored "guys, please post in threads" messages on top of that opieop

Vincent Cantin14:12:25

If most people agree, we admins can delete the spoilers and copy/paste a short what-to-do notice.

Vincent Cantin14:12:21

But I won't be watching the chan before I finish my solutions.

misha16:12:41

I don't see any value in pursuing this: • it is extra work for moderators, and deleting others' messages is not justified at all. • moderation will always be late, and spoilers will have time to spoil. • the spoiling window closes fast even without moderation, and by the end of the same day open code snippets become more convenient to browse than drilling down the threads (where code formatting sucks: not even 80 chars wide! ) • daily answers thread is horrible solution, because there is no nesting thread-in-tread. But with top level link or code - thread can have related dedicated discussion

pez18:12:21

Agree we do not need to use moderators for this. We can encourage each other. It’s not the end of the world if I see spoilers, just would be nice if most solutions were a click away.

erwinrooijakkers18:12:56

You can expect to see spoilers if you come here, same for http://old.reddit.com/r/adventofcode

misha19:12:23

it is "would be nice if most solutions were not a click away" for me though d I'd settle on "click to expand away" :) but generally, the key to disappointment is expectations: If 1) you expect this channel to be moderated, 2) someone new or not-caring posts spoiler code 3) moderator is busy solving, and is late to moderate, but 4) comes and deletes spoiler: • you are upset you saw a spoiler • moderator is upset there were spoilers to moderate • poster is upset their message is deleted

misha19:12:52

Extra work, but everybody is still upset. Not worth it, imo.

pez20:12:30

Not sure what tree you are barking up agains, @U051HUZLD. No-one expects to have a spoilerfree environment. I am just asking if people could consider putting their spoilers in a reply. Now and then someone new will not notice this practice. That’s how it is.

misha20:12:10

"barking", ok

pez23:12:48

I’m sorry. Didn’t mean it literally and didn’t mean to be rude.

st3fan15:12:27

I should put part3 in a loop instead of separate calls

erwinrooijakkers15:12:34

You should put your answer in a thread 😛

plexus15:12:01

posting links is fine, right? 🙂

pez15:12:15

Yeah, posting links is fine, me thinks.

plexus15:12:21

not sure if you were joking, I guess the 😛 is tongue in cheek

erwinrooijakkers15:12:43

yes it was a medium joke

erwinrooijakkers16:12:01

that way of posting is fine indeed there’s no code visible. although i think if you don’t want spoilers and hints don’t go here. i use this channel to check for nice solutions.

st3fan16:12:09

will someone pin a daily answers thread then?

st3fan16:12:18

i can't find the right thread

st3fan16:12:36

Day 3 Answers Thread .. Post your answers here

👍 6
mchampine01:12:09

(def raw-input (str/split-lines (slurp "resources/day03.data")))

(defn trees [inp [x y]]
  (let [expinp (map #(apply str (repeat 80 %)) inp)
        lines (rest (take-nth y expinp))]
    (count (filter #{\#} (map #(nth % %2) lines (range x 2300 x))))))

(trees raw-input [3 1]) ;; part 1
(apply * (map (partial trees raw-input) [[1 1] [3 1] [5 1] [7 1] [1 2]])) ;; part 2

pez23:12:46

With some pointers from @U051HUZLD (gaining me x200 speed!):

(ns pez.aoc2020.day-3
  (:require [clojure.string :as s]
            [pez.aoc2020.util :as util]))

(defn line-landing [dx line]
  (-> line
      (nth (mod dx (count line)))))

(defn count-trees [[dx dy] woods]
  (->> woods
       (take-nth dy)
       (map line-landing (take-nth dx (range)))
       (filter #{\#})
       (count)))

(comment
  (def input (util/fetch-input 3))
  (time
   (as-> input $
     (s/split-lines $)
     (map #(count-trees % $) [[1 1] [3 1] [5 1] [7 1] [1 2]])
     (apply * $)))
  ;; "Elapsed time: 1.75155 msecs"
  ;; => 3316272960
  )

st3fan16:12:52

Day 4 Answers Thread .. Post your answers here

mchampine14:12:10

My part 1

(def processed-input
  (->> (str/split-lines (slurp "resources/day04.data"))
       (partition-by empty?)
       (take-nth 2)
       (map #(apply str %))))

(defn allkeys? [l]
  (every? #(str/includes? l %)
          ["ecl:" "pid:" "byr:" "eyr:" "hcl:" "hgt:" "iyr:"]))

(count (filter allkeys? processed-input))

rjray21:12:22

This is my cleaned-up day 4 code: https://github.com/rjray/advent-2020-clojure/blob/master/src/advent_of_code/day04bis.clj. I don't know why I struggled with this one, or why the first pass at it was so cluttered.

st3fan16:12:18

I started to build a utils with some things like (load-input day tranformer-fn) to make things simpler

Stuart16:12:41

The leaderboard is crazy, it takes me longer to read the puzzle description and parse what i've actually to do than it takes some people to solve part 1

☝️ 3
Vincent Cantin16:12:39

I noticed that it is possible to read the time at which people got their stars in the JSON file following the [API] link.

Vincent Cantin16:12:32

I mean in the Clojurian leaderboard.

Vincent Cantin16:12:49

Today, the fastest was about 16 minutes (5:16 a.m. UTC)

nate16:12:35

in the past there has been a github repo with a list of links to individual repos with advent solutions, has anyone started that yet this year?

plexus16:12:03

there's one in the channel topic, but it only mentions 2017 and 2018, although it did just get a commit

misha16:12:41

I don't see any value in pursuing this: • it is extra work for moderators, and deleting others' messages is not justified at all. • moderation will always be late, and spoilers will have time to spoil. • the spoiling window closes fast even without moderation, and by the end of the same day open code snippets become more convenient to browse than drilling down the threads (where code formatting sucks: not even 80 chars wide! ) • daily answers thread is horrible solution, because there is no nesting thread-in-tread. But with top level link or code - thread can have related dedicated discussion

plexus16:12:38

So what you're saying is you actually prefer people to post their answers directly inline?

misha17:12:27

inline is fine with me. And it is way better than any moderation fuzz around it (which is 70% of today's messages). There are plenty of places where moderation is organic, and, more importantly, expected. I don't think it fits here, specifically because gains are so tiny, but cost is not.

st3fan17:12:24

@qmstuart i've given up on the leader board .. also because I'm in EST I would have to stay up till midnight and then start hacking on a solution. So instead I am fine collecting stars and just writing nice solutions. I'm more than happy if I am actually able to solve these with my current Clojure skills. And learn a few new tricks from others.

12
Stuart17:12:08

@st3fan yeah, puzzle go live at 5am my time. No way am I getting out of bed that early!

st3fan17:12:15

5am I could do! 🙂

plexus18:12:05

here it's 6am, which somehow because of the pandemic is later than when I usually get up 🙂

😮 6
erwinrooijakkers18:12:28

6am i made today and hopefully tomorrow again 🙂 really nice to see the clock ticking

Jeff Evans19:12:11

does everyone get different inputs?

Jeff Evans19:12:30

ah, yes. opening incognito reveals this: Puzzle inputs differ by user. Please log in to get your puzzle input.

st3fan21:12:48

Yup no cheating!

Jeff Evans22:12:16

not cheating, just curious 🙂

Jeff Evans22:12:20

I checked the FAQ but couldn’t figure it out… is there a day limit to finish the last problem? Not planning to actually tackle the last one on Christmas day…

rjray23:12:58

No day limit on any of the problems (people often go back to previous years as practice). But you won't get a positional ranking for any solution that takes more than 24 hours.