one thing I'm doing is really looking at medley https://github.com/weavejester/medley/blob/master/src/medley/core.cljc sure to come in handy
Iβm scratching my head as to why many of these arenβt in clojure.core
assoc-some
is a really good one
hows the weather up there?
for real, assoc-some
, deref-swap!
, dissoc-in
weather up here: cold. -10C (14F). fireplace is on and working on some cljs so canβt complain π
its cold here today as well 0C
you live in Fredericton?
I'm looking on the map
I do! about 10 minutes outside of town
and its anglophone mostly?
itβs an anglophone bastion in an otherwise bilingual-or-french-focused province, yep
It's actually a pretty good looking town
I grew up in new england
Connecticut coast line
it ainβt half bad π a little on the conservative side for my liking....
otherwise great
and new england is great
unrelated: my colleague Angus Fletcher is doing AoC as well - https://github.com/angusiguess/advent-of-code2016 - he says you and he met in an elevator one time, not sure where haha
@fellshard ^ pin away!
You, too, have the power to pin in the palm of your hand :)
really! I had no idea!
private leaderboards are perhaps the best addition to AoC this year
compete with your friends rather than.... fail to get in the top 100 every day π
thats sweet!!
so when you say its a bit conservative ...
you mean social interactions? politically?
or in that rural provincial way?
politically, in that rural provincial way. anecdote: there was a small chance that a strip club was going to open up. in order to thwart such an endeavor, the city swooped in and paid the lease on the empty building in question to eliminate the option. they are still paying that lease on that empty building to this day.
Isn't that what zoning laws are usually for? Hah. That's a painful way to solve a problem.
^ yeah the taxpayers agree. lol.
:shrug_emoji:
well they could at least be paying the strippers with that money...
it was a joke that I'm sure has been made many times up there
it wasnβt a small sum of money either; something like $500,000 for 5 or 10 years of empty building or something
holy crap!
so all you have to do if your building isn't rented ...
bahahaha I hadnβt considered that path
not a bad idea
(this particular building is right in the heart of downtown, so I suspect thatβs why they are willing to go the distance to prevent it from happening)
yeah but geez the could have started a tech incubator, 3d printing shop, or something
office space for start ups
yeah im puzzled as to why itβs notβ¦ somethingβ¦ yet
one could argue a strip club as a form of tech incubation
oh really ... the town is THAT backward
(the building in question - former nightclub https://www.google.ca/maps/@45.9626913,-66.6454743,3a,75y,43.99h,87.09t/data=!3m6!1e1!3m4!1sjwsC3AHYW5OjL7oYI3EZKg!2e0!7i13312!8i6656?hl=en )
It really is a nice looking town
come party!
lol
though Iβll admit that my particular employer has done nothing but irritate me for lack of willingness to adopt cljs (even though our entire backend is clojure)
so maybe not the best employer for, you know, the author of figwheel
Employers are prickly things
There's always the 'introduction by insubordination' tactic
"Well, too bad, because XYZ is already using it >:)"
Haha Iβve seriously considered that approach
(I have yet to pull this off, because consulting is very, very difficult to pull that off with)
Structured consulting firm, not freelance
all of the above said WRT conservativeness @bhauman : itβs also a university town where the students make up something like 25% of our population during the school year, so thereβs no small amount of more modern mindsets around
i tend to surround myself with those groups π
gotcha
the rotate-vec
method is still bothering me
(defn rotate-left [v i]
(let [c (count v)]
(vec (take c (drop (mod i c) (cycle v))))))
What's bugging you about it?
I noticed one of the pinned ones was pretty compact, it just concat
ed take
and drop
.
https://github.com/amirci/aoc_clj/blob/master/src/aoc/2016/day8.clj#L13
^ big fan of that
What if...
(defn shift
[l n]
(let [n (- (count l) n)
[first-part second-part] (split-at n l]]
(vec (concat second-part first-part))))
I have a big soft spot for destructuring. This is what happens when you learn ML... >_>
But probably not worth it at that point, just yak shaving
what about transients?
I've not used them yet. How would you apply them here?
Ahh, think I see. You'd perform mutations on the screen using transients, since the intermediates don't need to be used elsewhere.
(defn rotate-left [v x]
(let [v (vec v) c (count v) offset (mod x c)]
(loop [i 0 accum (transient [])]
(if (= i c)
(persistent! accum)
(recur (inc i) (assoc! accum i (get v (mod (+ offset i) c))))))))
so here is a more traditional imperative rotate
and ... simple benchmarking shows little difference
With a structure this size, yeah. Would probably make some difference with more operations / a bigger 'screen'.
oh shoot, transducers rock it though
(defn rotate-left2 [v i]
(let [c (count v)]
(sequence (comp (drop (mod i c)) (take c)) (cycle v))))
4 times as fast
todays problem doesnβt seem overly hard
but as I havenβt done yesterdays, ill have to do both later
I'm at a total loss today, I get completely different results when I paste today's string in raw than when I suck it in through a file. (the latter totally not being recognized by regexes even though it works fine when tested by hand)
And the former not giving a correct answer.
oh snap. you mean day 9?
if youβre having a hard time, then I feel as though I may have drastically underestimated the problem :^
It's not that hard, no
Finally got it, but was being stymied by technical issues
Will have to dig into it later π
Holy moly, parinfer deals strangely with parentheses in any position
Can't tell if it's parinfer or proto repl actually
.... /sigh. Okay, lesson learned. Good ol' re-matches
was stymied by the newline at the end of the input.
Same thing π
Time to start using re-find instead...
Given how often this seems to happen in these coding challenges, maybe I should come up with a quick set of parsing methods for easy utility...
it's hard to say... but maybe worth it
like parse numbers with separator
though sometimes it depends how you use it...
More like 'lop off this pattern from the beginning, hand me the matched groups and the remainder of the string'
Very dumb greedy parser
yes, one the regex libraries in haskell has exactly that
Don't do what I did. Mine takes more than three hours to run π
well all the test cases pass, and everything seems correct, but says I have the wrong answer
oooops found a bug
by the way I used trampoline for easy recursive parsing
mnespor, for the last one, do you build out a string still or do you just consume the string and find the length?
The recursion depth doesn't require trampoline, though I did end up using mutual recursion...
I just consume the string and find the length. Tail call optimization turned the recursion into a loop for me
You only have to go as deep as any grouping of repeater tags ends up nesting.
I consume characters until the first marker, drop the marker, and push its expansion back into the input
(def data (string/trim (slurp (io/resource "day9.txt"))))
(defn parse-dir [d]
(let [[_ directive & args] (re-matches #"(\((\d+)x(\d+)\)).*" (apply str d))]
(cons (u/to-ints args) (list (drop (count directive) d)))))
(defn parse-directive [d]
(let [[[cnt rpt] xs] (parse-dir d)
part (take cnt xs)]
[(apply concat (repeat rpt part))
(drop cnt xs)]))
(defn parse* [accum d]
(cond
(empty? d) accum
(= (first d) \() (let [[res rst] (parse-directive d)]
#(parse* (vec (concat accum res)) rst))
:else #(parse* (conj (vec accum) (first d)) (rest d))))
(defn parse [d]
(trampoline parse* [] d))
ahh
that's what I have so far haven't looked at the second part yet
In the end you're building a string that's hundreds of thousands, if not millions of characters long
I'm guessing you're shuffling your heap quite a bit trying to allocate new strings
Consider this: inside of a repetition tag and the region it affects, do any of the tags have any influence on characters outside of that region?
thinking
(Hmm, there's actually nothing in the specification that guarantees that...)
I think so?
I'm pretty sure they only generate input that satisfies the above. It could be I got a lucky input, but that seems like a constraint they intended to add, given the 'not enough memory to decompress' comment.
In this case, the first (9x2) ends at E, but the nested (9x2) covers up to I:
(9x2)(9x2)ABCDEFGHIJ
(9x2)ABCDE(9x2)ABCDEFGHIJ
ABCDE(9x2ABCDE(9x2)ABCDEFGHIJ
ABCDE(9x2ABCDEABCDEFGHIABCDEFGHIJ
I don't think any of the real inputs split a marker like that, however
(wasn't there a puzzle last year that asked you to tailor your solution to your input instead of solving the general case?)
I don't recall, but that implicit constraint is almost necessary to make the problem work as desired here.
There's almost certainly a constraint that forbids inputs like (5x3)(5x3)A
yeah that would be insane
I mean you could still have an algorithm that does that, and just assumes you'll return to the original string to consume when you run out of characters in the current region... but at that point you're in this really weird state, where the order of evaluation doesn't actually make sense....
hmmm wait a minute it looks like processing it backwards may be equivalent for problem 2
oh dang!!
Actually yeah, order of execution is more important
Consider (9x2)(5x2)abcde
Do you get (5x2)abcd(5x2)abcde
, or (9x2)abcdeabcde
?
(well, ignoring the parenthesis overlap, but you get the idea of how this could play out)
thinksing
What might that look like? It's probably not enough to seek backward to the first marker:
(5x3)(5x3)AAAB
(5x3)AAAAAAAAAAAAAAAB
AAAAAAAAAAAAAAAAAAAAAAAAAB
I think they tailored the input such that you don't have to worry about boundary crossing like that, too much ambiguity involved
I think backward may be equivalent in this case
(= (parse (concat "(10x2)" (parse "(5x2)abcde")))
(parse2 "(10x2)(5x2)abcde"))
It won't be. (5x3)(5x3)AAAAB
would expand to (5x3)(5x3)(5x3)AAAAB
if evaluated from the left, and that clearly blows up
So they can't hand you input like that
Expanding from the right leaves you with AAAAA...AAB
oh, so the real inputs could be equivalent backward
if there isn't boundary crossing
but that is a long shot
Is this boundary crossing? (6x3)(1x3)A
Yeah
Wait no
It's boundary crossing if the inner input consumes characters beyond the outer input
(1x6)(2x2)ABCD
Oh, I get it
(1x6)
only extends through A, (2x2)
extends beyond A necessarily
That makes working backward complicated. (6x3)(1x3)A
is valid forward, but not backward
A. I don't think they gave inputs like that
B. The examples they give work left to right, outer to inner, and I think that's an intentional cue
interesting
So it should be equivalent to the 'expand single tag and prepend the result' method
But you can chop out a bunch of work assuming that the boundary is never crossed, since that leads to absurd ambiguities in the spec
From the spec for part 1: > To decompress this marker, take the subsequent 10 characters and repeat them 2 times. Then, continue reading the file after the repeated data.
backwards doesn't work π
now I don't why I thought it did
its obvious why
now I'm obsessed with getting it to run fast...
π
My next move would be to quit bouncing between seqs and strings and using regexes, and just manually chew through the character stream instead
But even as I have it now, string conversions and all, the calculation time is very short
So that's more a memory usage optimization than anything
Hey I was a bit late to start todays... I'm on part 2 and I'm wondering if we are agreeing or not whether the boundaries can overlap?
It seems you could just parse it recursively if you don't allow overlap. That would be nice...
Based on a sample set of one - my own - I don't believe they intended for boundaries to overlap, no.
I see, thank you.
(spoilers) Here's some discussion on boundary crossing in day 9 inputs: https://www.reddit.com/r/adventofcode/comments/5hgd1f/day_9_part_2_everyone_assumes_it_but_its_not/dazzrm5/
The part I don't understand is, "The puzzle is about trying to get the user to do some kind of recursive expansion". But can you assume recursive expansion will work? I thought, "You can't"
so for me memoization was the key trimming all that computation, I had a crazy input
my expansion was 10gigs: 10,931,789,799
and I had to count and not accumulate
the result
10 GIGS? holy cow
I think I have that right my answer was 10,931,789,799 characters
yep thats 10 Gigs
this would have been better as a bash script
my solution runs in 4 seconds
Yeah, exactly
Don't expand - just tally
Since no boundaries are crossed, you can safely say 'recursively count the decompression of this tag's region. Now multiply by this tag's number of repetitions.'
The recursion level is pretty flat for most inputs I'm guessing, so very little stack problems and you can deal with finite chunks of the input at a time.
well that was a bastard, I remember this pain from from last year now...