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
fingertoe 2019-12-04T00:01:56.156300Z

Wasted a lot of time on silly misplaced parens error on this one. ๐Ÿ˜‰ https://github.com/jreighley/aoc2019/blob/master/src/aoc/aoc3.clj

Average-user 2019-12-04T00:55:29.156500Z

Have you tried parinfer or parindent?

fingertoe 2019-12-04T01:02:36.156700Z

I use cursive and parinfer. It was my distance function that added the absolute values of the two vectors. Since it was all on the same line, it didnโ€™t help

(+ (abs x)) (abs y)
instead of
(+ (abs x) (abs y))
The function was returning the correct number on the y deltas but 0 on the x deltasโ€ฆ

mpcjanssen 2019-12-04T02:03:37.158Z

@erwinrooijakkers nice tip, using peek instead of last shaved 500ms of the 7s.

2019-12-04T03:04:16.162Z

I'm getting a late start. Are we using the same leaderboard as last year?

2019-12-04T03:05:49.162500Z

(or I could just look at channel topic, I suppose)

dpsutton 2019-12-04T03:13:51.163Z

I havenโ€™t seen the same style this year @norman

kenj 2019-12-04T03:15:48.164Z

Only made it through part 1 of day 3 while slacking at work towards the end of the dayโ€ฆ no one noticed the Clojure instead of Python on my screen ๐Ÿคท https://github.com/KennyMonster/aoc_2019/blob/c2dfdfffdc4447c34aa6a7c90b0a763d10da8713/src/day_3.clj

fellshard 2019-12-04T03:59:53.164200Z

There's some days when I've needed a break to do some real programming and get my brain moving again before going back to 'real work'. So long as it hasn't cut into the hours I'm contracted to bill, anyway. ๐Ÿ™‚

Average-user 2019-12-04T04:28:33.164500Z

Yep

mchampine 2019-12-04T05:55:16.165800Z

Puzzle 4 was way easier than the last two. I count 8 lines of code for Part 1, with a single line altered to adapt the part 1 solution to part 2.

uneman 2019-12-04T06:04:07.165900Z

same here. puzzles are being opened amid of my work time ๐Ÿคซ

mchampine 2019-12-04T06:20:56.170200Z

Actually, just a single character change for part 2. I have a test for repeated digits that looks like this: (some #(&lt;= 2 (count %)) (partition-by identity (str n)) For part 2, just changing the โ€œ<=โ€ to โ€œ=โ€ was sufficient.

mpcjanssen 2019-12-04T06:29:45.171400Z

i used frequency on the list of digits

yuhan 2019-12-04T06:33:32.173200Z

Still find it awesome how lisps allow you to do things like #((case part 1 &lt;= 2 =) 2 (count %))

mchampine 2019-12-04T06:35:16.174Z

@mpcjanssen ?? You mean frequencies? But that doesnโ€™t care about order, so I donโ€™t see how it would detect sequential duplicates differently than non-sequential ones..

mpcjanssen 2019-12-04T06:37:05.175200Z

@mchampine you are right. it did give the right answer though

mchampine 2019-12-04T06:37:21.175400Z

Surprising!

mpcjanssen 2019-12-04T06:37:43.176200Z

no because the digits are increasing

mpcjanssen 2019-12-04T06:37:56.176800Z

so any same digits are consecutive

mchampine 2019-12-04T06:37:57.176900Z

Ahh.. got it.

mchampine 2019-12-04T06:38:08.177200Z

Good call.

mpcjanssen 2019-12-04T06:38:28.177700Z

rationalisation after the fact ๐Ÿ™‚

mpcjanssen 2019-12-04T06:38:50.178400Z

did not completely think this through before

lilactown 2019-12-04T06:38:59.179Z

yes the duplicate check can be pretty dumb if you take advantage of that

lilactown 2019-12-04T06:39:25.179500Z

I still used dedupe though for part 1

lilactown 2019-12-04T06:39:51.180Z

https://github.com/Lokeh/advent-2019/blob/master/day4.org

๐Ÿ‘ 1
uosl 2019-12-04T09:57:09.190Z

#(apply &lt;= (digits %))
Damn, so simple!

yenda 2019-12-04T11:29:17.194500Z

why do you divide by 10000 though I don't get it why not something like (<= 100000 x 999999)

yenda 2019-12-04T11:30:21.195200Z

or (= 6 (count (str digits)))

lilactown 2019-12-04T15:55:46.204200Z

the first one would probably have been better, yeah

lilactown 2019-12-04T15:56:10.204800Z

I wanted to avoid converting to a string if possible

mchampine 2019-12-04T06:45:51.181300Z

Wow, using spec. Neat. Btw, you can do a quick and dirty digits conversion with (map read-string (map str (str 123456)))

mpcjanssen 2019-12-04T06:54:55.182700Z

also nice literal coding with org-babel

mpcjanssen 2019-12-04T06:55:35.183600Z

the environments are as interesting as the code itself

๐Ÿ‘ 1
mpcjanssen 2019-12-04T06:57:46.184Z

for mine https://github.com/mpcjanssen/aoc2019/blob/master/day04.ipynb

mchampine 2019-12-04T07:06:14.185500Z

Yes, tried org-babel a while back. Pretty great stuff you can do. I was mixing bash, python, clojure, and LaTeX as I recall.

karlis 2019-12-04T08:52:53.189100Z

apart from the somewhat vague description for puzzle #2, today was quick & easy: https://github.com/skazhy/advent/blob/master/src/advent/2019/day4.clj

2019-12-04T10:17:29.190800Z

hereโ€™s mine https://gist.github.com/roman01la/c607849e71e6de11549976428cd3d6a6

2019-12-04T10:18:18.191600Z

@karlis indeed, it took me a while to decypher description of the 2nd part

๐Ÿ‘ 1
โ˜๏ธ 1
karlis 2019-12-04T10:33:24.191700Z

neat use of frequencies! That's a method I only seem to use during advent of code ๐Ÿ˜„

genmeblog 2019-12-04T10:51:05.192Z

Oh, this is so great solution. Clever. I overcomplicated a thing this time.

mpcjanssen 2019-12-04T11:15:38.192700Z

Smart regex for increasing

2019-12-04T11:29:41.194700Z

Try a first time with "filter wrong values", but my predicates were pretty bad, so my evaluation "never" finishes. I re-write it in a dirty (but successful) way. https://github.com/Charlynux/advent-of-code-2019/blob/master/day04/day04.clj

2019-12-04T12:28:25.195500Z

regex turned out to be much faster than parsing and comparing digits

taylor 2019-12-04T13:02:09.200400Z

I think each year there are a few problems like day 4 pt. 2 that seem almost intentionally vagueโ€ฆ https://github.com/taylorwood/advent-of-code/blob/master/src/advent_of_code/2019/4.clj

๐Ÿ‘ 1
misha 2019-12-04T14:26:47.200700Z

I did (= (seq s) (sort-by identity compare s))) 10 times slower than regex

James Adam 2019-12-04T15:31:27.202300Z

Mine is ugly, but it works: https://github.com/rhinoman/aoc2019/blob/master/src/aoc2019/day4.clj

jrwdunham 2019-12-04T15:31:36.202600Z

@taylor nice digits func to convert an int to a seq of digits without string manipulations. I would have never thought to do it that way

1
James Adam 2019-12-04T15:32:59.203400Z

@jrwdunham my solution initially used string manipulation, I got about 10x speedup when I cut out all of the type conversions ๐Ÿ™‚

tws 2019-12-04T16:02:16.205Z

bug in num-to-digits for 0.

user=&gt; (num-to-digits 0)
[]

misha 2019-12-04T16:14:44.206600Z

(time
  (let [MIN      382345
        MAX      843167
        int-vec  (fn [n] (->> n str (map str) (mapv #(Integer/parseInt % 10))))
        low      (int-vec MIN)
        high     (int-vec MAX)
        too-low  #(neg? (compare % low))
        in-range #(neg? (compare % high))
        pwds     (for [a (range 0 10)
                       b (range a 10)
                       c (range b 10)
                       d (range c 10)
                       e (range d 10)
                       f (range e 10)
                       :let [n [a b c d e f]]
                       :when (->> n frequencies vals (some #{2}))]
                   n)]
       (->> pwds
         (drop-while too-low)
         (take-while in-range)
         (count))))
"Elapsed time: 13.145288 msecs"
=> 290

๐Ÿ˜ 1
misha 2019-12-04T16:14:52.206800Z

:troll:

misha 2019-12-04T16:16:26.207600Z

James'es times on my input and laptop are: "Elapsed time: 159.510294 msecs" "Elapsed time: 324.308817 msecs"

misha 2019-12-04T16:19:07.208Z

roman's times: "Elapsed time: 227.731395 msecs" "Elapsed time: 172.91049 msecs"

Mario C. 2019-12-04T16:31:37.209Z

Day 4 part 2 was written very poorly.

โ˜๏ธ 1
uosl 2019-12-04T16:31:41.209200Z

very cool. using for like that to avoid the intermediate numbers

Mario C. 2019-12-04T16:32:51.210700Z

Not too fond of the 10 mins wait after submitting x number of wrong answers

misha 2019-12-04T16:34:11.211600Z

btw, I understood part 2 immediately by looking at examples, don't know why so many were confused. (however, there were few similar requirements in previous years' puzzles, so I might have just recognized it)

uosl 2019-12-04T16:35:18.212600Z

same here. although I tend to jam the examples into my tests before I think too much over the problem description

Mario C. 2019-12-04T16:35:29.213100Z

I thought I did too until my answers were wrong

Mario C. 2019-12-04T16:35:54.214200Z

222222 should or shouldn't be valid?

uosl 2019-12-04T16:35:59.214500Z

shouldn't

uosl 2019-12-04T16:36:03.214800Z

maybe you're unlucky and got input data with an extra edge case

Mario C. 2019-12-04T16:36:15.215200Z

repeating 2 and its not apart of a larger group

Mario C. 2019-12-04T16:36:20.215500Z

its the only group

uosl 2019-12-04T16:36:41.216100Z

oh no, now I'm confused. it should be

uosl 2019-12-04T16:37:04.216900Z

there must exist at least one consecutive group with a length of 2+

misha 2019-12-04T16:37:15.217100Z

also this is why I did not use frequencies initially, because I recalled "2 but not 3+ in a row", and thought of letters, and did not figure out that there can only be 1 streak per digit, and can't be e.g. 11xx1x.

misha 2019-12-04T16:37:39.217500Z

I think it should not, because it is more than 2 in a row

uosl 2019-12-04T16:37:54.217600Z

^ this is part 1. part 2 is exactly 2 instead of 2+

misha 2019-12-04T16:39:21.218500Z

@regen "at least one 2+" for part1, "at least one exactly 2" for part 2

Mario C. 2019-12-04T16:40:32.218800Z

Should 123455 work?

misha 2019-12-04T16:40:49.219200Z

yes, for both

misha 2019-12-04T16:41:10.219700Z

*unless outside the range

Mario C. 2019-12-04T16:41:14.219900Z

But isn't the 55 part a larger group of repeating?

misha 2019-12-04T16:41:31.220400Z

group is just same digit several times in a row

Mario C. 2019-12-04T16:41:37.220600Z

same reason 123444 didn't count

misha 2019-12-04T16:41:54.221Z

444 is a group of 3: three 4 s in a row

misha 2019-12-04T16:42:27.221400Z

consecutively

misha 2019-12-04T16:43:21.222600Z

(partition-by identity coll) gives you groups : (partition-by identity "123444") => ((\1) (\2) (\3) (\4 \4 \4))

Mario C. 2019-12-04T16:43:28.222800Z

Thats not how I understood it. Which was my complaint since it was left up to interpretation

Mario C. 2019-12-04T16:43:38.223200Z

I figured 333444 should work

Mario C. 2019-12-04T16:43:57.223800Z

since the 33 or 44 are not part of a larger group

Mario C. 2019-12-04T16:44:36.224600Z

but you are making the case that it wont work since they are both groups of 3

misha 2019-12-04T16:45:06.225200Z

group of 2 is two of the same digits in a row. larger group is tree or more of the same digit in a row

misha 2019-12-04T16:45:14.225400Z

I am, yes. 333444 should be invalid

misha 2019-12-04T16:45:47.225900Z

because it has 2 groups of size 3 each,

Mario C. 2019-12-04T16:46:39.226200Z

the two adjacent matching digits are not part of a larger group of matching digits.I understood this as: As long the repeating digit is not part of the largest group of all groups then it is valid.

Mario C. 2019-12-04T16:47:53.227300Z

So 122333 is valid and so would 222333

Mario C. 2019-12-04T16:48:11.228100Z

but not 123444 since the repeating digit is part of the larger group

misha 2019-12-04T16:48:23.228500Z

yes. here, 33____ and 33__ are two adjacent matching digits but both are part of a larger group of matching digits 333___

misha 2019-12-04T16:48:37.228800Z

same for 44_ and _44 in 444

James Adam 2019-12-04T16:48:40.229Z

It doesn't like it when the first digit is 0

genmeblog 2019-12-04T16:48:44.229200Z

122333 is valid because has 22.

Mario C. 2019-12-04T16:49:39.231Z

222333 has two groups. Each of size 3 meaning there is no larger group. Since they are both the same

misha 2019-12-04T16:49:55.231800Z

122333 is valid, because there is only 2 2 in a row, 222333 in invalid, because there is 3 2 in a row

genmeblog 2019-12-04T16:50:00.232Z

No, there are two larger groups.

misha 2019-12-04T16:50:24.232300Z

. (map count (partition-by identity "122333")) => (1 2 3) ;; has group of exactly 2 numbers (map count (partition-by identity "222333")) => (3 3) ;; does not have group of exactly 2 numbers

Mario C. 2019-12-04T16:51:19.233Z

There we go. They should have just written that ^

Mario C. 2019-12-04T16:51:30.233300Z

> does not have group of exactly 2 numbers

misha 2019-12-04T16:52:59.234700Z

this is why people here bragged about "part 2 was just 1 char diff commit!": (->> ... (some #(<= 2 %))) for part 1 and (->> ... (some #(= 2 %))) for part 2

Mario C. 2019-12-04T17:02:09.235500Z

Not for me. I kept thinking "Oh I get it now." Type the answer in and getting "Sorry wrong answer. Plz wait 10 mins before submitting again."

Mario C. 2019-12-04T17:02:36.236Z

But wasn't going to bed until I got the goldie

Mario C. 2019-12-04T17:02:51.236500Z

first part was easy though

misha 2019-12-04T17:03:16.237100Z

happened a lot to me in other puzzles. It is not in the aoc interests to make it obvious to you what needs to be done, hence lots of text, indirection in terminology, random bold font highlights, "by the ways", ambiguous examples

jrwdunham 2019-12-04T17:04:34.238200Z

I wrote a crazy regex to get dec4/pt2 which i'm sharing for laughs. (Liking the concise and sane strategies I'm seeing here):

jrwdunham 2019-12-04T17:04:36.238500Z

(def pattern
  (re-pattern
   (str
    "("
    "(^|[^1])11($|[^1])"
    "|"
    "(^|[^2])22($|[^2])"
    "|"
    "(^|[^3])33($|[^3])"
    "|"
    "(^|[^4])44($|[^4])"
    "|"
    "(^|[^5])55($|[^5])"
    "|"
    "(^|[^6])66($|[^6])"
    "|"
    "(^|[^7])77($|[^7])"
    "|"
    "(^|[^8])88($|[^8])"
    "|"
    "(^|[^9])99($|[^9])"
    "|"
    "(^|[^0])00($|[^0])"
    ")")))

๐Ÿ˜… 2
misha 2019-12-04T17:05:27.239300Z

zeroes are invalid here :opieop:

jrwdunham 2019-12-04T17:05:42.239800Z

right. still works though.

misha 2019-12-04T17:05:59.240100Z

because you filter them out earlier/later

jrwdunham 2019-12-04T17:06:11.240800Z

filter them out earlier, with yet another regex

jrwdunham 2019-12-04T17:06:27.241400Z

(filter (fn [d] (re-find #"(.)\1" d)))

jrwdunham 2019-12-04T17:06:51.242200Z

oh, nevermind, that doesn't do it...

misha 2019-12-04T17:07:13.242600Z

I'd like to see concise pattern including all of it: range, group size, ascendingness

yuhan 2019-12-04T17:07:40.243200Z

@misha I did a similar optimization to only iterate through non-decreasing digit-vectors ๐Ÿ™‚

(defn incr [ds]
  (let [d (peek ds)]
    (if (= 9 d) ;; recursive
      (let [ds* (incr (pop ds))]
        (conj ds* (peek ds*))) ;; roll over using prev digit
      (conj (pop ds) (inc d)))))

(iterate incr [1 4 6 8])
;; =&gt; ([1 4 6 8]
;;     [1 4 6 9]
;;     [1 4 7 7]
;;     [1 4 7 8]
;;     [1 4 7 9]
;;     [1 4 8 8]
;;     [1 4 8 9]
;;     [1 4 9 9]
;;     [1 5 5 5]
;;     [1 5 5 6]
;;     ...)

misha 2019-12-04T17:08:25.244300Z

yeah, but anything in user space is likely to be slower than for :opieop:

misha 2019-12-04T17:10:13.244400Z

slower and less readable :kappa:

jrwdunham 2019-12-04T17:11:18.245200Z

@misha my un-aptly named monotonically-increasing? filter seems to be correctly filtering out the 0s

misha 2019-12-04T17:12:30.246Z

I pointed that out so you could speed up regex

yuhan 2019-12-04T17:12:51.246400Z

I replaced the nested for clauses in your solution with (for [n (iterate incr [0 0 0 0 0 0]]) and got a 13.5 msec => 9.0 msec speed up

jrwdunham 2019-12-04T17:13:02.246800Z

i see. See any way to make the regex more concise, with backreferences and lookahead/behind fanciness?

misha 2019-12-04T17:14:07.247100Z

not even gonna try :d:

jrwdunham 2019-12-04T17:14:35.247300Z

haha.

jrwdunham 2019-12-04T17:14:42.247500Z

Yes, also not fast: part 1: Elapsed time: 485.806268 msecs; part 2: Elapsed time: 578.42914 msecs.

misha 2019-12-04T17:14:49.247600Z

what is incr? inc?

yuhan 2019-12-04T17:15:17.247900Z

the recursive function I posted above

yuhan 2019-12-04T17:16:22.248300Z

(not great at naming things)

jrwdunham 2019-12-04T17:16:40.248800Z

taking out the 0s disjunct in the regex speeds things up by 50-100ms

๐ŸŽ๏ธ 1
misha 2019-12-04T17:17:30.248900Z

is it consistent speed up? do you consistently get 13ms on my snippet? for me it fluctuates +-2ms

misha 2019-12-04T17:18:03.249700Z

or did you just compare 9ms on your machine to 13 on mine? :troll: different code too!

2019-12-04T17:18:11.250100Z

For speed AND idiomatic code it's probably better to do it in Rust

yuhan 2019-12-04T17:19:31.250400Z

Both on my machine with the same inputs

misha 2019-12-04T17:20:08.250900Z

for is idiomatic :)

misha 2019-12-04T17:20:20.251Z

nice

Average-user 2019-12-04T17:28:01.251500Z

Yep, i didn't thought about using for. But my solution is more general (not only for six digit length numbers)

Average-user 2019-12-04T17:28:12.251700Z

And is only slightly slower

misha 2019-12-04T17:45:55.252400Z

of course! hence the trollface in my snippet )

๐Ÿ™‚ 1
yuhan 2019-12-04T17:46:39.253200Z

got it down to 3.6 ms using transducers ๐Ÿ™‚ (measured using Criterium's quick-bench)

yuhan 2019-12-04T17:49:46.253600Z

(defn day4
  [start end part]
  (let [dv     (fn [n] (mapv #(Character/getNumericValue %) (str n)))
        dv<    (fn [a b] (= -1 (compare a b)))
        startv (dv start)
        endv   (dv end)
        incr   (fn [ds] ;; increase digit vector until it satisfies non-decreasing condition
                 (let [d (peek ds)]
                   (if (= d 9) ;; recursive
                     (let [ds* (incr (pop ds))]
                       (conj ds* (peek ds*))) ;; roll over using prev digit
                     (conj (pop ds) (inc d)))))
        pw?    (fn [xs]
                 (some #((case part 1 <=, 2 =) 2 (count %))
                   (partition-by identity xs)))]
    (transduce
      (comp
        (drop-while #(dv< % startv))
        (take-while #(dv< % endv))
        (filter pw?))
      (completing (fn [n _] (inc n)))
      0
      (iterate incr (vec (repeat (count startv) (first startv)))))))

(day4 124075 580769 1) ;; => 2150
(day4 124075 580769 2) ;; => 1462

3
lilactown 2019-12-04T18:00:31.254200Z

wow nice!

jrwdunham 2019-12-04T18:17:21.255100Z

Nice @qythium, about 1msec faster than @dmarjenburghโ€™s solution in my timing.

taylor 2019-12-04T18:38:31.255200Z

the only other place Iโ€™ve ever used this is in coding interviews :lol:

taylor 2019-12-04T18:41:40.255700Z

I had a solution that worked for all the examples but not for my test input; took me like 6 submissions to get it right

2019-12-04T20:02:24.257600Z

Doing AOC last year was so much easier when I was on vacation for almost the entire month. I have a feeling I'm going to be playing catch up all month...

fellshard 2019-12-04T20:29:04.257900Z

Yeah, I may need to curb my participation for a while. Too busy.

fellshard 2019-12-04T20:29:31.258500Z

But I feel better about it knowing that I'm not aiming for leaderboard points. I'll learn what I'm aiming to, just more slowly.

fingertoe 2019-12-04T21:02:41.258600Z

I always feel like I am cheating when I use regex. That never stops me from being tempted. (Including today)

fingertoe 2019-12-04T21:21:08.260400Z

Simple enough: https://github.com/jreighley/aoc2019/blob/master/src/aoc/aoc4.clj Itโ€™s not too often that I use ns without a :require. The separated-pairs? fn seems a bit hacky, but effective.