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
bhauman 2016-12-09T02:10:21.000168Z

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

samueldev 2016-12-09T02:12:39.000170Z

I’m scratching my head as to why many of these aren’t in clojure.core

bhauman 2016-12-09T02:14:31.000171Z

assoc-some is a really good one

bhauman 2016-12-09T02:15:11.000173Z

hows the weather up there?

samueldev 2016-12-09T02:17:46.000174Z

for real, assoc-some, deref-swap!, dissoc-in

samueldev 2016-12-09T02:18:16.000175Z

weather up here: cold. -10C (14F). fireplace is on and working on some cljs so can’t complain πŸ™‚

bhauman 2016-12-09T02:20:03.000176Z

its cold here today as well 0C

bhauman 2016-12-09T02:20:28.000177Z

you live in Fredericton?

bhauman 2016-12-09T02:20:42.000178Z

I'm looking on the map

samueldev 2016-12-09T02:20:59.000179Z

I do! about 10 minutes outside of town

bhauman 2016-12-09T02:21:37.000180Z

and its anglophone mostly?

samueldev 2016-12-09T02:21:54.000181Z

it’s an anglophone bastion in an otherwise bilingual-or-french-focused province, yep

bhauman 2016-12-09T02:22:18.000182Z

It's actually a pretty good looking town

bhauman 2016-12-09T02:22:49.000183Z

I grew up in new england

bhauman 2016-12-09T02:22:58.000184Z

Connecticut coast line

samueldev 2016-12-09T02:23:17.000185Z

it ain’t half bad πŸ™‚ a little on the conservative side for my liking....

samueldev 2016-12-09T02:23:25.000186Z

otherwise great

samueldev 2016-12-09T02:23:32.000187Z

and new england is great

samueldev 2016-12-09T02:24:23.000188Z

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

bhauman 2016-12-09T02:26:30.000191Z

@fellshard ^ pin away!

fellshard 2016-12-09T02:27:30.000192Z

You, too, have the power to pin in the palm of your hand :)

πŸ‘ 1
bhauman 2016-12-09T02:27:51.000194Z

really! I had no idea!

samueldev 2016-12-09T02:30:00.000195Z

private leaderboards are perhaps the best addition to AoC this year

samueldev 2016-12-09T02:30:14.000196Z

https://puu.sh/sJ6CE/686782fd68.png

samueldev 2016-12-09T02:30:36.000198Z

compete with your friends rather than.... fail to get in the top 100 every day πŸ˜›

bhauman 2016-12-09T02:31:54.000199Z

thats sweet!!

bhauman 2016-12-09T02:32:33.000200Z

so when you say its a bit conservative ...

bhauman 2016-12-09T02:32:54.000201Z

you mean social interactions? politically?

bhauman 2016-12-09T02:33:07.000202Z

or in that rural provincial way?

samueldev 2016-12-09T02:34:08.000203Z

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.

fellshard 2016-12-09T02:35:15.000204Z

Isn't that what zoning laws are usually for? Hah. That's a painful way to solve a problem.

samueldev 2016-12-09T02:35:27.000205Z

^ yeah the taxpayers agree. lol.

samueldev 2016-12-09T02:35:46.000206Z

:shrug_emoji:

bhauman 2016-12-09T02:36:04.000207Z

well they could at least be paying the strippers with that money...

πŸ˜‚ 1
bhauman 2016-12-09T02:36:34.000208Z

it was a joke that I'm sure has been made many times up there

samueldev 2016-12-09T02:36:58.000209Z

it wasn’t a small sum of money either; something like $500,000 for 5 or 10 years of empty building or something

bhauman 2016-12-09T02:37:08.000210Z

holy crap!

bhauman 2016-12-09T02:37:31.000211Z

so all you have to do if your building isn't rented ...

samueldev 2016-12-09T02:37:53.000212Z

bahahaha I hadn’t considered that path

samueldev 2016-12-09T02:38:05.000213Z

not a bad idea

samueldev 2016-12-09T02:38:52.000214Z

(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)

bhauman 2016-12-09T02:39:26.000216Z

yeah but geez the could have started a tech incubator, 3d printing shop, or something

bhauman 2016-12-09T02:39:46.000217Z

office space for start ups

samueldev 2016-12-09T02:39:57.000218Z

yeah im puzzled as to why it’s not… something… yet

samueldev 2016-12-09T02:40:07.000219Z

one could argue a strip club as a form of tech incubation

bhauman 2016-12-09T02:40:39.000220Z

oh really ... the town is THAT backward

bhauman 2016-12-09T02:42:36.000222Z

It really is a nice looking town

samueldev 2016-12-09T02:42:47.000223Z

come party!

bhauman 2016-12-09T02:42:52.000224Z

lol

samueldev 2016-12-09T02:43:06.000225Z

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)

samueldev 2016-12-09T02:43:17.000226Z

so maybe not the best employer for, you know, the author of figwheel

fellshard 2016-12-09T02:43:55.000227Z

Employers are prickly things

fellshard 2016-12-09T02:44:10.000228Z

There's always the 'introduction by insubordination' tactic

πŸ‘ 2
fellshard 2016-12-09T02:44:24.000229Z

"Well, too bad, because XYZ is already using it >:)"

samueldev 2016-12-09T02:44:40.000230Z

Haha I’ve seriously considered that approach

fellshard 2016-12-09T02:44:50.000231Z

(I have yet to pull this off, because consulting is very, very difficult to pull that off with)

fellshard 2016-12-09T02:45:06.000232Z

Structured consulting firm, not freelance

samueldev 2016-12-09T02:45:54.000233Z

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

samueldev 2016-12-09T02:45:59.000234Z

i tend to surround myself with those groups πŸ™‚

bhauman 2016-12-09T02:47:18.000235Z

gotcha

bhauman 2016-12-09T02:49:15.000236Z

the rotate-vec method is still bothering me

bhauman 2016-12-09T02:49:34.000237Z

(defn rotate-left [v i]
  (let [c (count v)]
    (vec (take c (drop (mod i c) (cycle v))))))

fellshard 2016-12-09T02:50:56.000239Z

What's bugging you about it?

fellshard 2016-12-09T02:51:27.000240Z

I noticed one of the pinned ones was pretty compact, it just concated take and drop.

samueldev 2016-12-09T02:53:44.000244Z

^ big fan of that

fellshard 2016-12-09T02:53:49.000245Z

What if...

fellshard 2016-12-09T02:55:57.000246Z

(defn shift
  [l n]
  (let [n (- (count l) n)
        [first-part second-part] (split-at n l]]
    (vec (concat second-part first-part))))

fellshard 2016-12-09T02:56:19.000247Z

I have a big soft spot for destructuring. This is what happens when you learn ML... >_>

fellshard 2016-12-09T02:56:58.000248Z

But probably not worth it at that point, just yak shaving

bhauman 2016-12-09T03:11:04.000249Z

what about transients?

fellshard 2016-12-09T03:14:54.000250Z

I've not used them yet. How would you apply them here?

fellshard 2016-12-09T03:23:43.000251Z

Ahh, think I see. You'd perform mutations on the screen using transients, since the intermediates don't need to be used elsewhere.

bhauman 2016-12-09T04:07:04.000252Z

(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))))))))

bhauman 2016-12-09T04:07:29.000253Z

so here is a more traditional imperative rotate

bhauman 2016-12-09T04:12:46.000254Z

and ... simple benchmarking shows little difference

fellshard 2016-12-09T04:33:03.000255Z

With a structure this size, yeah. Would probably make some difference with more operations / a bigger 'screen'.

bhauman 2016-12-09T04:52:11.000256Z

oh shoot, transducers rock it though

bhauman 2016-12-09T04:52:33.000257Z

(defn rotate-left2 [v i]
  (let [c (count v)]
    (sequence (comp (drop (mod i c)) (take c)) (cycle v))))

bhauman 2016-12-09T04:52:59.000259Z

4 times as fast

samueldev 2016-12-09T05:40:12.000260Z

todays problem doesn’t seem overly hard

samueldev 2016-12-09T05:40:22.000261Z

but as I haven’t done yesterdays, ill have to do both later

fellshard 2016-12-09T06:03:44.000262Z

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)

fellshard 2016-12-09T06:03:54.000263Z

And the former not giving a correct answer.

samueldev 2016-12-09T06:05:56.000264Z

oh snap. you mean day 9?

samueldev 2016-12-09T06:06:13.000265Z

if you’re having a hard time, then I feel as though I may have drastically underestimated the problem :^

fellshard 2016-12-09T06:08:49.000266Z

It's not that hard, no

fellshard 2016-12-09T06:08:57.000267Z

Finally got it, but was being stymied by technical issues

fellshard 2016-12-09T06:09:08.000268Z

Will have to dig into it later 😐

fellshard 2016-12-09T06:24:42.000269Z

Holy moly, parinfer deals strangely with parentheses in any position

fellshard 2016-12-09T06:24:57.000270Z

Can't tell if it's parinfer or proto repl actually

fellshard 2016-12-09T07:16:18.000271Z

.... /sigh. Okay, lesson learned. Good ol' re-matches was stymied by the newline at the end of the input.

abarylko 2016-12-09T07:21:51.000272Z

Same thing 😊

fellshard 2016-12-09T07:23:35.000273Z

Time to start using re-find instead...

fellshard 2016-12-09T07:28:03.000274Z

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...

abarylko 2016-12-09T07:29:25.000275Z

it's hard to say... but maybe worth it

abarylko 2016-12-09T07:29:34.000276Z

like parse numbers with separator

abarylko 2016-12-09T07:30:00.000277Z

though sometimes it depends how you use it...

fellshard 2016-12-09T07:36:03.000278Z

More like 'lop off this pattern from the beginning, hand me the matched groups and the remainder of the string'

fellshard 2016-12-09T07:36:12.000279Z

Very dumb greedy parser

abarylko 2016-12-09T07:38:22.000281Z

yes, one the regex libraries in haskell has exactly that

mnespor 2016-12-09T14:53:58.000286Z

Don't do what I did. Mine takes more than three hours to run πŸ˜•

bhauman 2016-12-09T16:03:27.000287Z

well all the test cases pass, and everything seems correct, but says I have the wrong answer

bhauman 2016-12-09T16:05:46.000288Z

oooops found a bug

bhauman 2016-12-09T16:06:05.000289Z

by the way I used trampoline for easy recursive parsing

fellshard 2016-12-09T16:07:07.000290Z

mnespor, for the last one, do you build out a string still or do you just consume the string and find the length?

fellshard 2016-12-09T16:07:35.000291Z

The recursion depth doesn't require trampoline, though I did end up using mutual recursion...

mnespor 2016-12-09T16:07:56.000292Z

I just consume the string and find the length. Tail call optimization turned the recursion into a loop for me

fellshard 2016-12-09T16:08:16.000294Z

You only have to go as deep as any grouping of repeater tags ends up nesting.

mnespor 2016-12-09T16:08:33.000295Z

I consume characters until the first marker, drop the marker, and push its expansion back into the input

bhauman 2016-12-09T16:09:01.000296Z

(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))

fellshard 2016-12-09T16:09:05.000297Z

ahh

bhauman 2016-12-09T16:09:20.000298Z

that's what I have so far haven't looked at the second part yet

fellshard 2016-12-09T16:09:22.000299Z

In the end you're building a string that's hundreds of thousands, if not millions of characters long

fellshard 2016-12-09T16:09:54.000300Z

I'm guessing you're shuffling your heap quite a bit trying to allocate new strings

fellshard 2016-12-09T16:11:16.000301Z

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?

mnespor 2016-12-09T16:11:47.000302Z

thinking

fellshard 2016-12-09T16:12:33.000303Z

(Hmm, there's actually nothing in the specification that guarantees that...)

mnespor 2016-12-09T16:15:13.000304Z

I think so?

fellshard 2016-12-09T16:15:19.000305Z

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.

mnespor 2016-12-09T16:16:21.000306Z

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

mnespor 2016-12-09T16:16:56.000307Z

I don't think any of the real inputs split a marker like that, however

mnespor 2016-12-09T16:19:23.000309Z

(wasn't there a puzzle last year that asked you to tailor your solution to your input instead of solving the general case?)

fellshard 2016-12-09T16:21:01.000310Z

I don't recall, but that implicit constraint is almost necessary to make the problem work as desired here.

mnespor 2016-12-09T16:27:14.000311Z

There's almost certainly a constraint that forbids inputs like (5x3)(5x3)A

bhauman 2016-12-09T16:29:06.000312Z

yeah that would be insane

fellshard 2016-12-09T16:36:24.000313Z

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....

bhauman 2016-12-09T16:40:00.000314Z

hmmm wait a minute it looks like processing it backwards may be equivalent for problem 2

bhauman 2016-12-09T16:40:13.000315Z

oh dang!!

fellshard 2016-12-09T16:40:51.000316Z

Actually yeah, order of execution is more important

fellshard 2016-12-09T16:41:26.000317Z

Consider (9x2)(5x2)abcde

fellshard 2016-12-09T16:42:07.000318Z

Do you get (5x2)abcd(5x2)abcde, or (9x2)abcdeabcde?

fellshard 2016-12-09T16:42:27.000319Z

(well, ignoring the parenthesis overlap, but you get the idea of how this could play out)

bhauman 2016-12-09T16:44:06.000321Z

thinksing

mnespor 2016-12-09T16:50:06.000322Z

What might that look like? It's probably not enough to seek backward to the first marker:

(5x3)(5x3)AAAB
(5x3)AAAAAAAAAAAAAAAB
AAAAAAAAAAAAAAAAAAAAAAAAAB

fellshard 2016-12-09T16:50:09.000323Z

I think they tailored the input such that you don't have to worry about boundary crossing like that, too much ambiguity involved

bhauman 2016-12-09T16:50:46.000324Z

I think backward may be equivalent in this case

bhauman 2016-12-09T16:51:09.000325Z

(=   (parse   (concat  "(10x2)"  (parse "(5x2)abcde")))
       (parse2 "(10x2)(5x2)abcde"))

fellshard 2016-12-09T16:52:23.000326Z

It won't be. (5x3)(5x3)AAAAB would expand to (5x3)(5x3)(5x3)AAAAB if evaluated from the left, and that clearly blows up

fellshard 2016-12-09T16:52:27.000327Z

So they can't hand you input like that

fellshard 2016-12-09T16:52:49.000328Z

Expanding from the right leaves you with AAAAA...AAB

mnespor 2016-12-09T16:52:50.000329Z

oh, so the real inputs could be equivalent backward

bhauman 2016-12-09T16:53:42.000330Z

if there isn't boundary crossing

bhauman 2016-12-09T16:54:13.000331Z

but that is a long shot

mnespor 2016-12-09T16:57:08.000332Z

Is this boundary crossing? (6x3)(1x3)A

fellshard 2016-12-09T17:06:41.000333Z

Yeah

fellshard 2016-12-09T17:06:47.000334Z

Wait no

fellshard 2016-12-09T17:07:02.000335Z

It's boundary crossing if the inner input consumes characters beyond the outer input

fellshard 2016-12-09T17:07:50.000337Z

(1x6)(2x2)ABCD

mnespor 2016-12-09T17:08:50.000339Z

Oh, I get it

fellshard 2016-12-09T17:09:16.000340Z

(1x6) only extends through A, (2x2) extends beyond A necessarily

mnespor 2016-12-09T17:09:33.000342Z

That makes working backward complicated. (6x3)(1x3)A is valid forward, but not backward

fellshard 2016-12-09T17:09:43.000343Z

A. I don't think they gave inputs like that

fellshard 2016-12-09T17:09:58.000344Z

B. The examples they give work left to right, outer to inner, and I think that's an intentional cue

mnespor 2016-12-09T17:10:03.000345Z

interesting

fellshard 2016-12-09T17:11:20.000346Z

So it should be equivalent to the 'expand single tag and prepend the result' method

fellshard 2016-12-09T17:11:38.000347Z

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

fellshard 2016-12-09T17:16:01.000348Z

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.

bhauman 2016-12-09T17:24:49.000349Z

backwards doesn't work 😞

bhauman 2016-12-09T17:27:25.000350Z

now I don't why I thought it did

bhauman 2016-12-09T17:27:39.000351Z

its obvious why

bhauman 2016-12-09T17:46:37.000352Z

now I'm obsessed with getting it to run fast...

fellshard 2016-12-09T17:50:47.000353Z

πŸ˜„

fellshard 2016-12-09T17:51:32.000354Z

My next move would be to quit bouncing between seqs and strings and using regexes, and just manually chew through the character stream instead

fellshard 2016-12-09T17:51:56.000355Z

But even as I have it now, string conversions and all, the calculation time is very short

fellshard 2016-12-09T17:52:18.000356Z

So that's more a memory usage optimization than anything

andrew.sinclair 2016-12-09T19:59:42.000357Z

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?

andrew.sinclair 2016-12-09T20:00:38.000358Z

It seems you could just parse it recursively if you don't allow overlap. That would be nice...

fellshard 2016-12-09T20:03:33.000359Z

Based on a sample set of one - my own - I don't believe they intended for boundaries to overlap, no.

andrew.sinclair 2016-12-09T20:09:01.000360Z

I see, thank you.

mnespor 2016-12-09T21:37:28.000361Z

(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/

andrew.sinclair 2016-12-09T22:55:48.000366Z

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"

bhauman 2016-12-09T23:02:47.000367Z

so for me memoization was the key trimming all that computation, I had a crazy input

bhauman 2016-12-09T23:03:30.000368Z

my expansion was 10gigs: 10,931,789,799

bhauman 2016-12-09T23:03:46.000369Z

and I had to count and not accumulate

bhauman 2016-12-09T23:03:51.000370Z

the result

samueldev 2016-12-09T23:04:33.000371Z

10 GIGS? holy cow

bhauman 2016-12-09T23:05:59.000372Z

I think I have that right my answer was 10,931,789,799 characters

bhauman 2016-12-09T23:06:13.000373Z

yep thats 10 Gigs

bhauman 2016-12-09T23:06:49.000374Z

this would have been better as a bash script

bhauman 2016-12-09T23:07:18.000375Z

my solution runs in 4 seconds

fellshard 2016-12-09T23:29:33.000376Z

Yeah, exactly

fellshard 2016-12-09T23:29:37.000377Z

Don't expand - just tally

fellshard 2016-12-09T23:30:36.000378Z

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.'

fellshard 2016-12-09T23:31:06.000379Z

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.

bhauman 2016-12-09T23:59:41.000381Z

well that was a bastard, I remember this pain from from last year now...