and I finally got around to doing day 3 https://github.com/bhauman/advent-of-clojure/blob/master/src/advent-2018/day03.clj
Why do you say APL is a different paradigm? Aside from laziness it's pretty similar - just a very different notation.
Because I don’t know APL :)
Day 4 discussion, with spoilers
[1518-09-19 23:52] Guard #2083 begins shift
[1518-02-25 00:51] wakes up
[1518-02-28 00:34] wakes up
[1518-04-29 00:54] wakes up
Rather sneakily, the example data isn’t in the same format the actual input is.
They don’t give you any hint of that apart from > consider the following records, which have already been organized into chronological order
My solution to day 4 https://github.com/pesterhazy/advent2018/blob/master/src/advent/puzzle04.clj#L42
Spent around half the time on parsing/understanding the file format
yeah I found the description less than clear
but I guess vague specifications is a real-world programming scenario 🙂
In the description they say: > While this example listed the entries in chronological order, your entries are in the order you found them. You’ll need to organize them before they can be analyzed.
It was a key realization that there's only one useful chunk of info per line. Also, the specific line format they give means you can sort it in standard lexicographic order to get the correct sequence of events right off the bat, no interpretation of the data required. 🙂
I did sort lexicographicallz
but you still need to match guard-ids, interval starts and ends no?
Yeah, you’re right. I missed it because it’s not in the place I expected to find it (task description, rather than input format description)
That also is a real-world programming scenario: don’t read specs before first coffee :woman-facepalming:
Reminds me ☕
Yep. One piece of info to parse per line: Guard ID or minute.
And event type 🙂
True; I attached that as a tag afterwards, though, since you need to know which type it is to parse correctly in the first place
Solved day 4: https://github.com/borkdude/advent-of-cljc/tree/master/src/aoc/y2018/d04
In CLJ:
Testing aoc.y2018.d04.borkdude
part-2 took 40.23 msecs
part-1 took 3.80 msecs
@pesterhazy It seems our solutions are quite similar
When reading the puzzle, I thought “strategy 1” was trying to mislead me, since they wrote that there were two strategies and I thought you had to come up with another better strategy 😉
took me a while to parse it, but as usual, regex to the rescue 🙂
here’s my day 4 https://github.com/taylorwood/advent-of-code/blob/master/src/advent_of_code/2018/4.clj reached for clj-time and instaparse b/c why not 🙂
My solution to day 4 https://github.com/benfle/advent-of-code-2018/blob/master/day4.clj
and mine: https://github.com/genmeblog/advent-of-code-2018/blob/master/src/advent_of_code_2018/day04.clj
If I had time I would have refactored into something like @tsulej. If you have the proper data structure with minute-level stats for each guard, the 2 solutions can be very concise.
Yes, I think that proper data structure is crucial here. I spent most of my time to find one. The same applies for day 3.
oh yeah, I always forget you can give sort-by
another argument like (sort-by val > the-things)
without it you can always call (last)
which can be obviously slower
(comp - val)
cool hack 🙂
yeah I did the comp thing
lol!!
Day 4 https://github.com/mfikes/advent-of-code/blob/master/src/advent_2018/day_04.cljc
of course, (max-key val …)
our add-minutes
solution is quite the same
or wait, no, it isn’t 🙂
ah you save a map of guard -> minutes
nice to see another use of max-key
; I rarely ever have a use for it
the concision of some of these solutions is impressive 👏
@mfikes very nice!
yeah I was surprised at the amount of (first (sort-by ...))
I’ve been seeing.
max-key
often gets forgotten
I’m not done yet (done 1/2), but took a look at this channel, and max-key instead of sort-by in the existing solution … which slowed things down. Did you find it more performant?
nah, just what I want
I haven't been concerned with performance for any of the problems yet
later in the schedule performance becomes more important
I looked at it, but passed it by because I thought it wasn't quite what I wanted. I'll take another look to see what I'm missing.
Are you thinking (apply max-key...)
has a heavier cost for, say, a map of minute tallies?
(…actually might have been the effect of something triggering in the background… I need to check again once I’ve got a charger 🙂 )
@fellshard I had the same: max-key passed my mind but then I thought: oh this is for map keys or something
why isn’t it called max-by
I think the prospect of (apply max-key...
on 60 elements had me a bit worried, I forget what the rules are for slapping a bunch of arguments in there, even rest-args
that works
@fellshard (apply + (repeat 1000000 1))
seems to work ok in CLJ and CLJS, but (apply + (repeat 10000000 1))
is fast in Clojure but very slow in CLJS (at least in Lumo 1.8.0)
In Java varargs are passed as an array AFAIK so it should be fine. Not sure why it's so slow in CLJS
Probably GC?
Math.max.apply(null, new Array(1000000).fill(0))
blows the stack...
(apply max (range 100000000000))
works though
@pesterhazy Update to Lumo 1.9.0. You'll see (apply + (repeat 1000000 1))
a few hundred times faster. Why? This is the result of optimizations made in ClojureScript after last year's Advent of Code. 🙂
changed my max-frequency function. I really should use max-key more often. I think I only remember it until Advent of Code comes along again https://github.com/borkdude/advent-of-cljc/commit/24fa6344c3c64a3fc242d7b2a784df7b73bace8a
Lumo 1.8.0:
cljs.user=> (type (repeat 1000000 1))
cljs.core/LazySeq
Lumo 1.9.0:
cljs.user=> (type (repeat 1000000 1))
cljs.core/Repeat
More info: https://clojurescript.org/news/2018-03-26-release#_reducible_sequence_generators
I’ve browsed clojure.core, but keep forgetting about many of the functions in there. I totally forgot about max-key
and rolled my own. That said, I used what I rolled in a couple of other ways, so it wasn’t a waste
@mfikes the advent of code comes full circle!
it's much faster indeed 🎉
also a good occasion to upgrade lumo
now it's 10x faster than Clojure
$ lumo
cljs.user=> (time (apply + (repeat 10000000 1)))
"Elapsed time: 65.706720 msecs"
10000000
$ clj
Clojure 1.9.0
user=> (time (apply + (repeat 10000000 1)))
"Elapsed time: 657.798409 msecs"
10000000
performance is weird
In this case, Lumo may be running at native speed. See https://www.youtube.com/watch?v=LopU-kMpe8I
anyone know why (read-string "01")
or (read-string "02")
... all the way up to 07 work just fine but (read-string "08")
and (read-string "09")
throw exceptions saying it is an invalid number? Would assume all would or none would.
08 is octal
ah
Well, malformed octal 🙂
I've used this almost every day so far:
(defn str->int [^String s]
(Integer/parseInt s))
yeah, for cljc read-string was just faster, but better not to use it for these scenarios (in real code)
is the type annotation really necessary?
@adammiller not sure if you do advent-of-cljc, but there’s aoc.utils/parse-int
for cross platform
yes, I saw that. Actually just moved my day 3 solution there yesterday....just locally though.
@adammiller welcome to submit individual puzzles for any day
ok, i'll see about moving my day 4 and then submit them. Thanks!
@borkdude it was necessary when I tried it with 1.10-RC2
Try it in the REPL!
I thought I tried that and it didn't work. Is fixed by the ^string metadata?
It worked for me on day 1 ¯\(ツ)/¯
Hmmm.... Dang. Wonder what I had problems with...
Maybe it was just the int
function...
int
is a cast to int
but yeah, java Long/parseLong
permits + and -: https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#parseLong(java.lang.String)
I’m forever wrapping Long/parseLong in a function. It’s a source of never ending frustration for me that Clojure doesn’t have to-long and to-double
The function reader literal syntax is pretty terse: #(Long/parseLong %)
. Much nicer than a top level (defn ...)
form, if that's what you've been using.
I almost had a heart-attack when I checked out the real data and saw it had multiple "wakes up" in a row, after having written my solution. Then I realized that it just wasn't chronologically ordered. Then sort
came to the rescue 🌸