#Advent of Code

1262 messages · Page 2 of 2 (latest)

radiant pilot
#

my sleep schedule is fucked enough

#

I did the parsing and wrote a function to check the extremal coordinates so I could see if the naive algorithm would be enough for part 1 and ||it turns out it totally would be so I'll do that tomorrow and then cry when it's not enough for part 2||

#

I have an idea for a not-naive algorithm but

flint tinsel
#

part 2 isnt that hard lol

radiant pilot
#

lol ofc you're done with p1 already

flint tinsel
#

lmao check the leaderboards

radiant pilot
#

ya 3000 people done

#

did you just copy from 2018/17 or did you have to implement it?

#

maybe im missing something with the not-naive idea I have cuz it seems tricky to implement

#

maybe i'll have an insight when its not midnight

#

I have a presentation to prepare for tomorrow anyway so I can't get too distracted by this tonight sadly :/

flint tinsel
#

wouldve taken me longer to figure out what i did 4 years ago than to reimplement it, naive solution should be enough here

#

oh the message isnt pinned

muted wharf
radiant pilot
radiant pilot
#

did you actually look at your map?

#

this is a slice of mine lmao

thorn surge
#

Mine had some of ``` #####

                       ##### #####


                    ##### ##### #####


                 ##### ##### ##### #####


              ##### ##### ##### ##### #####


          ######

       ###### ######

    ###### ###### ######

 ###### ###### ###### ######
###### ###### ###### ######``` Strangest cave I've seen.
thorn ibex
#

That's not mine but it's nice so I share:

radiant pilot
flint tinsel
#

wasted half an hour because i forgot the numbers could be negative ._.

radiant pilot
#

??? all of mine are very positive

#

I take it back, there is a single negative number

#

thanks

flint tinsel
#

dafaq how did i make it in top 1000 for part 2 despite wasting so much time in part 1 lol

flint tinsel
radiant pilot
#

scheme has arbitrary precision numbers but thanks

flint tinsel
#

i meant the answer should be 1 lower than what your program outputs, if you didnt take into account that beacon

#

thats the other gotcha that tripped me up

radiant pilot
#

oh you mean because it's in the row

#

yes I was accounting for that

#

I didn't connect 2e6 with the not-scientific-notation for 2mil

radiant pilot
#

my algorithm for part 2 had so many bugs.

#

First it was off-by-one errors. Then it was adding when I should've been overwriting. Then it was being too greedy with assuming that ||any improvement would be enough as opposed to having to work harder to get the best possible point to skip to||

#

I mean i'm asking for it by programming at 1 am

#

but

#

still comfortably top 3000, which says a lot about the difficulty of part 2 I guess

#

I think as a curiosity I'd like to implement inversion lists, they are directly applicable to this problem and lead to a very fast algorithm for both parts

flint tinsel
#

inversion lists would have to be non-overlapping

radiant pilot
#

the algorithm for taking the union of two inversion lists ensures that

#

wouldn't be a very useful representation of sets otherwise

flint tinsel
#

the problem has overlapping intervals though, dunno how you would account for that

radiant pilot
#

compute the (simple) interval associated with each sensor in a particular row, take the union of all of those

flint tinsel
#

oh, i thought it was a way more optimized algorithm lol

radiant pilot
#

i mean inversion lists are asymptotically optimal for what they do

flint tinsel
#

i have a solution in O(n^2 logn) time where n=#sensors

radiant pilot
#

The runtime of my solution depends on the actual density of coverage (but it runs instantly so)

#

Inversion lists would be O(n) in the number of sensors

#

The multi-union might actually be nlogn

flint tinsel
#

wait, are you talking about part 1 or 2 here?

radiant pilot
#

2

flint tinsel
#

would be interesting to see how fast your code runs then, got mine down to 12ms

radiant pilot
#

I didn't try to optimize further, my general AOC feeling is if i have to wait long enough for the answer that i can react to the fact it hasn't shown up yet, it's too slow

#

(I'm not at my computer anymore)

thorn ibex
#

for part 2 || I've just run part 1 for every y and keep the only line with two intervals (I was merging intervals for part 1) ||

#

Btw I didn't have to subtract 1 for part 1 as no beacon where on my line

flint tinsel
#

that's what I initially did too

urban lagoon
#

I think I might be a few days behind

elder bane
#

I feel like I could do Day 15 by hand...

urban lagoon
#

just do it in desmos

#

the correct answer to day 15 is to get better scanners obviously

elder bane
#

Well, even given just a distance and the devices knowing their location, you could triangulate the position with three in 2D, or four in 3D.

radiant pilot
#

im sure part 1 could be done by hand. gfl on part 2 tho

urban lagoon
#

I haven't even started day 15

#

still working on day 13

#

I have the logic done

#

(not tested but who cares about testing)

#

the input parsing is the problem

#

(also I switched to an oop solution)

elder bane
#

Part 1: At x=2000000, how many squares will be taken up?

urban lagoon
#

and part 2 is how many total squares I assume?

radiant pilot
#

Answering that would be spoilers!

urban lagoon
#

lol

#

oh uh btw

#

how bad is part 2 of day 13

elder bane
urban lagoon
#

maybe it's some kind of product mess?

elder bane
#

I'm wondering if it is to do all of them...

flint tinsel
#

triangulation wont work here, since its perfectly valid to have 3 sensor-beacon pairs that dont cover each other's ranges at all

elder bane
#

Yep. My solution idea for Day 15 is to crunch some numbers.

radiant pilot
#

Yeah part 1 is just some math. Interval merging is optimal but just actually computing the set of points covered is very fast too

thorn surge
#

I've hit a brick wall in AoC day 16 part 1. While I can solve the example input, the puzzle input is taking too long. After taking a peek at reddit || it appears that people are using DFS to find the optimal path in under a second. I've left my implementation running for over 15 minutes, until I cancelled it. I'd prefer to figure this out with resorting to reading other peoples code, but I have no idea what I might be getting wrong. Clearly my O(n_valves !) algo is bonkers, even after some short cutting.||

radiant pilot
#

I haven't done day 16 yet, but i was going to now. Unfortunately I forgot to put my code on GitHub before I left Montreal so I've lost my AOC library that I've been adding to over the month.

thorn surge
#

It's too late for me to do any more - hopefully tomorrow is nicer for me.

muted wharf
#

||If you visit a valve, you can store what happened till now, you don't need to revisit a node||

thorn surge
#

|| There are n_valves! possible paths, I don't see how to reduce that number significantly.||

elder bane
#

Then you could run it in less time...

thorn surge
#

Yes, I'm already ||examining only the rooms with non-zero valves.||

elder bane
#

Even the worst algorithm I can think of only runs in O(2^x) time...

radiant pilot
#

In a tree with n nodes and e edges, there are significantly fewer than n! Paths

thorn surge
#

Moving through e.g. {A, B, C}, has you can visit them as ABC, ACB, BAC, or BCA etc, which is 3! (perhaps "paths" is not the correct technical term?)

muted wharf
#

And also, that doesn'T account for edges

thorn surge
#

huh? n options for the choice of the first node, then (n-1) for the next, etc? I think we're getting to the centre of my confusion. I don't see how number of edges affects this.

#

I don't have a tree of valves, not clear how I'd transform this into one?

muted wharf
thorn surge
#

Yes, you can activate the valves in any order.

muted wharf
#

Sure, but is any order sensible?

#

Also, you very much have a graph of valves

thorn surge
#

That might the the insight I need, I'll think on it.

#

Graph, yes, tree, no.

elder bane
#

I'm only thinking of a multi-linked list that I can traverse...
Breadth-First, though.

elder bane
#

...You'd actually have a multi-graph (a vertex connected multiple times to another vertex).
Breadth-first, while being wildly inefficient, can tell you exactly where you'll be in 30 moves.

muted wharf
radiant pilot
#

I possibly see what you're missing. ||The DFS is not searching the graph.||

#

Imagine the input graph

   AA:0
  /    \
BB:1  CC:1
thorn ibex
#

DFS is O(V + E) so very fast

#

you are doing brute force, not DFS

#

btw I havn't done day 16 yet

thorn surge
#

The tree I'm searching has over n! nodes, so I'm looking at the wrong tree.

thorn ibex
#

It looks like || DFS is not the solution, but maybe only a step to compute the graph of the non-zero valves, and the brute force should only branch between non-zero valves ||

#

But in that case || DFS is not the right choice I think, it must be a Dijkstra like to compute the minimum path between the current valve and the next non-zero one||

thorn surge
#

I used || Floyd–Warshall || for that.

thorn ibex
#

yep and even with that the brute force is too long?

#

I'll do it tomorrow

#

btw I searched a bit and in english it's called || https://en.wikipedia.org/wiki/Backtracking I don't think a DFS would be useful in that problem, don't know where you found that||

Backtracking is a class of algorithms for finding solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a candidate ("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution.The classic textbook exam...

radiant pilot
#

"DFS" is commonly used in english interchangeably with that term.

#

it's a DFS over ||the search space||

elder bane
flint tinsel
#

good enough >_>

radiant pilot
#

someone on the haskell sub says the greedy algorithm solved his part 2

#

which is so unfair

#

for me it gives a (surprisingly close but) incorrect answer

#

but the sort of naive extension of part 1 did work, it just takes like 15s

#

part 1 is pretty much instantaneous

#

OTOH the new one seems easy enough.

flint tinsel
#

got into top 100 today, yay

thorn ibex
# thorn ibex I'll do it tomorrow

day 16 part 1 under 10ms (not reliable) I was using the example data set, 1.4s now.
with Clojure, without trying to optimize, but as Clojure is natively immutable backtracking algorithms are fast

#

Using || Floyd-Warshall + backtracking on non-zeros valves ||

radiant pilot
#

Very curious what ||periods and offsets|| you guys had today. My ||period is quite large|| but on the subreddit I see some people who have ||very small ones||.

flint tinsel
#

mine was ||period=1745||

radiant pilot
#

For the record, mine was ||period=3500||

#

Someone on the subreddit is saying theirs was ||period=35|| unless I'm really misunderstanding their code.

flint tinsel
#

that feels incredibly unlikely

radiant pilot
#

i know

#

he ||adds the height difference every time a rock stops|| and found ||period over that data||

flint tinsel
#

lmao a huge coincidence that it worked out

radiant pilot
#

but something about the jupyter notebook its in doesn't make sense because ||some of those differences are big, like >200, but obviously the most possible is 3. And yet nowhere in his code does it indicate that he drops many rocks before tracking the next difference...||

thorn surge
#

I found a ||period of 17457430|| but compared to yours I think I may have over counted.

#

My input ||length was~~ 10092~~10091|| does that vary between people?

radiant pilot
#

my input was one less than that

thorn surge
#

Sorry yes, mine was too.

radiant pilot
#

My guess is that ||however you're finding the period uses a metric for saying "yes, this is repeating" which is too strong||

thorn surge
#

My procedure was || don't check every cycle, instead I assumed it would be a multiple of the two cycle lengths (rock*wind) so I checked that often.|| Your answer tells me that was not necessarily the case.

radiant pilot
#

that is certainly not true, ||each rock cycle uses an inconsistent number of wind cycles||

#

well, not necessarily true, anyway.

thorn surge
#

I wasn't trying to find ||the minimum cycle length, it just hadn't occurred to me that shorter ones would exist.|| I just made sure that I would fine one.

radiant pilot
#

But you'll also find one if you just ||check every period until one works|| lol

#

I ||dropped the first 1000 deltas to give it time to converge|| and then ||checked every period from 10 to 5000 until one worked||

#

that all runs in less than half a second, the only slow part is generating ||enough deltas||

thorn surge
#

True, that would have been quicker, but I also had no idea ||when it would become periodic.||

flint tinsel
#

another easy one today lol

urban lagoon
#

"easy"

#

I probably shouldn't've even attempted AoC lol

#

it wasn't that bad until day 8

radiant pilot
#

part 1 was easy, part 2 looks also easy but im pretty tired so itll take me a while

#

||I'm thinking complement the input w.r.t. the bounding box; delete everything that can be reached from 0,0,0; use p1 solution to compute the surface area of the result and subtract it from the p1 result. If that's not right then I can also iterate that and PIE says it'll be correct once the complement set is empty||

radiant pilot
#

Nope, no issue. ||No mean solid things inside air pockets. I was fully expecting there to be some.||

#

I did waste about 15 minutes because I accidentally named a global variable min in my repl and couldn't figure out why all my functions broke when I reloaded the source file into the repl...

#

@urban lagoon this one really is easy (not "is really easy," though). The last two days were quite a difficulty spike for sure, but today's is back to reasonable levels. You can do it!

urban lagoon
#

wait

#

it actually is really easy

#

||if 2 cubes share 2 coords then they are connected||

#

||then, subtract one from the number of connected cubes, multiply it by 2, and subtract that from the number of cubes multiplied by 6||

#

oh btw I still haven't gotten 11 working

#

I really don't know what's wrong with it

radiant pilot
#

That algorithm sounds n^2 and nlogn is possible (effectively just n)

urban lagoon
#

idc if it's n^2

radiant pilot
#

But sure it should work i think

urban lagoon
#

this computer is fast enough to do it in 10 seconds

#

(I think)

thorn surge
radiant pilot
#

How? I'm not sure I believe that.

#

||Hashmaps are O(n log n).||

thorn surge
#

I'm talking about day 18, ||data can be stored in a 3D array. I only used a hash based store cause I was too lazy to set up the array.||

#

In case I got my wires crossed about which day we're talking.

radiant pilot
#

Oh. I mean, sure, that takes a lot more space though

#

but yeah, of course

#

🤦‍♂️

flint tinsel
#

everyone's having trouble with today's problem?

urban lagoon
#

which very much seems like a job for an AI

flint tinsel
#

it's definitely do-able under a second via tree search with some aggressive pruning

#

and i kinda doubt AI would get the optimal path

urban lagoon
#

I was hoping it'd just ask for the best blueprint, since then I could just guess

#

unfortunately not

thorn surge
#

Since day 19 looks like it uses ||the same algorithm as day 16, I've gone back to it.||

thorn ibex
#

ho you looked the leaderboard

#

didn't have time to do it yet + it's ||backtracking|| again so not very fun

thorn surge
#

Is this the right idea (in C++) for Day 16? ||``` void visit(int node, int time, int state, int flow, map<int, int> & cache) {
// Are we at a better point with the current valves turned on than last time we were at this point? if so, update value
cache[state] = std::max(cache[state], flow);
for(int next_valve = 1; next_valve < network->valve_count; next_valve++) { //For all valves
// Time remaining is time minus walking time, minus 1 minute to open valve
auto new_time = time - network->valve_dists.at(node).at(next_valve) - 1;
int valve_mask = (1 << next_valve);
if( (valve_mask & state) != 0 | | new_time <= 0 ) {
continue; // Don't go to the same valve twice, don't go to a valve if it means we run out of time.
}
// Go to new valve, update state so it's turned on, add its flow, repeat everything above.
auto new_flow = flow + (new_time * network->valve_flows.at(next_valve));
auto new_state = state | valve_mask;
visit(next_valve, new_time, new_state, new_flow, cache);
}
}

flint tinsel
#

that looks like it should work

#

actually, that pretty much matches 80% of my alrogithm for both parts

radiant pilot
#

The key to day 16 is reducing the search space which it looks like you've already done so yeah 👍

#

I haven't been able to look at today's sadly and probably can't until tomorrow

urban lagoon
thorn surge
#

Thank you both for the feedback. There must be something else wrong somewhere in my mess of code.

urban lagoon
#

I'm not looking at it because spoilers

#

even though I have basically no chance at day 16

radiant pilot
thorn ibex
thorn surge
#

It's AA and the non-zero valves only. It gives the correct answer for the example. int is at least 32 bits.

thorn ibex
#

then can you show your floyd-warshall maybe?

#

at the end you take which value of cache? AA (first) one? The max?

thorn surge
#

||for(auto i: rooms) { for(auto j: rooms) { // room_dists is populated as nodes are inserted. if(room_dists.count(std::pair(i.second.name, j.second.name)) == 0) { room_dists[std::pair(i.second.name, j.second.name)] = INT32_MAX; } } } for(auto k: rooms) { for(auto i: rooms) { for(auto j: rooms) { if( room_dists[std::pair(i.second.name, j.second.name)] > room_dists[std::pair(i.second.name, k.second.name)] + room_dists[std::pair(k.second.name, j.second.name)] ) { room_dists[std::pair(i.second.name, j.second.name)] = room_dists[std::pair(i.second.name, k.second.name)] + room_dists[std::pair(k.second.name, j.second.name)]; } } } } for(Valve_ID i = 0; i < valve_count; i++) { for(Valve_ID j = 0; j < valve_count; j++) { valve_dists[i][j] = room_dists[std::pair(valves[i].name, valves[j].name)]; } }||

#

I take the max of the cache, which works for the example, but it doesn't get that far with the puzzle input.

#

I haven't made a careful comparison of the output of my F-W, but it looks sensible.

#

I don't really know how to debug this - with logging there's too much, and stepping through a debugger is not very illuminating.

thorn ibex
#

Is room_dists initialized before?

thorn surge
#

yes as the rooms are added.

thorn ibex
#

by value of 1s?

thorn surge
#

yes

#

with ones for the adjacnet rooms, and 0 otherwise the map defaults to 0

thorn ibex
#

why do you count room_dists?

#

instead of room_dists[std::pair(i.second.name, j.second.name)] == 0

thorn surge
#

no good reason, I'll change that, thanks

thorn ibex
#

else it seems ok, btw C++ syntax is horrible but I'm not used to it

thorn surge
#

maps are a pain in C++

thorn ibex
#

Are you sure the parsing is ok?

#

because there's a different text when it leads to one valve or several

#

but it the example there is the case too

thorn surge
#

yes, that caught me out at first, but reading the flows and some spot checks of the room_dists, it looks good.

thorn ibex
#

because you used INT32_MAX, do you have any overflow when doing the sum?

#

try to change to like 1000

flint tinsel
#

okay i hope today's problem doesnt waste anyone else's 60 minutes so here's a clarification they didnt put in the prompt for some stupid reason:
if the number is greater than the length of the list, then you have to skip over the current number
e.g. [3],x,y -> x,[3],y not [3],x,y -> [3],x,y

#

incredibly dumb that they fail to mention it at all in the problem, and im demanding to speak to the manager for a refund on my hour wasted

thorn ibex
#

I don’t understand why it wouldn’t be x,3,y?

#

3,x,y -> x,3,y -> x,y,3 -> x,3,y

#

It’s just a circular list and there are many examples with rolling numbers

flint tinsel
#

:v what

#

oh my god I feel dumb now

#

in my defense, all the numbers in the example are small so I never see that case happening

thorn surge
#

I've wasted so much time on the other gotcha hidden in the input.

flint tinsel
#

ayy got rank 3 on part 2 🎉

thorn ibex
#

and not top 100 in part 1 😛

flint tinsel
#

lol was 109 for part 1

urban lagoon
#

day 24 just seems exteremely memory intensive

flint tinsel
#

I didn't use much memory

#

the blizzards positions are the same with respect to time

urban lagoon
#

what

#

I was thinking to just generate a really big tree

#

also no

#

the blizzards' positions are not the same with respect to time

flint tinsel
#

the tree size should be at maximum the size of your grid at each time interval

#

I meant it only changes with time lol

urban lagoon
#

yeah

#

the idea is that ||each child represents a position of your character||

#

||if the child represents a state where you are on a wall/blizzard, discard it||

#

||your character has 5 possible actions, so each chile generates 5 more||

#

||if a child has no children, discard it||

#

||also if a state is repeated, delete it||

#

||at the end of this process, find the shortest path to a completed scenario||

urban lagoon
#

day 25 actually seems doable

#

it's just base conversions

#

ok turns out conversion to this weird base is actually hard

urban lagoon
#

alright part 1 is basically solved

#

nvm then