Day 7! I wasn't able to complete yesterday's challenge in time, but I'm going to keep working and hopefully get caught up this weekend. Nevertheless, Advent waits for no DEV, and we must press onwards.
Today, we get the exciting task of putting together Santa's sleigh, and it doesn't seem like the instructions are quite up to IKEA's standards. They even provide us with a neat example graph! Di-graph? More like die-graph, amirite?
Just kidding, this should be fun! Good luck!
Top comments (14)
Javascript solution
I decided to create a tree to represent each Step, adding dependencies and dependents for each steap, and a sorting algorithm to sort steps about to processed (i.e. when it has no dependents).
Then, I use a BFS traversal, employing a queue to visit the steps. In the 1st part, if a step has been processed but still has dependents, I re-add it to the end queue. For the 2nd part, I don't need this because then it won't be picked up by another worker, it remains with the same worker for the rest of the duration of that step.
reader.js
07-common.js
07a.js
07b.js
Today I could figure out only the first part :( Wasted quite a bit of time because example input and real input had one big difference between data structures (and I assumed wrongly ;).
Part 1
readFile.php
Yeah, I wish the sample was more representative of the actual data. I struggled with getting this part 1 done, and was not ready for part 2, to many differences and I had already spent more time on day 7 than any other day
Fighting my way up the leaderboard.
My Python Solution
Part 1
Part 2
KotlinTinkerPop/Gremlin SolutionPart 1
I feel really bad, but I kept banging my head on graph walking, so I gave up and pulled in a graph database to handle that for me.
My first solution was just stepping through
g.V().not(inE()).order().by(property("name").value()).limit(1)
and then dropping each one.However, here's what a real property graph database solution would look like:
Notes: If you see
US
in the code, that's a quick kotlinization of the__
groovy dsl, which doesn't play nicely with IntelliJ.Part 2
Ok, now that I had a method for stepping through the graph, it was much easier to add resources and have time get updated in the DB as I traversed and deleted nodes.
At least, it would have been if I remembered how to gremlin. I spent more time than I'm willing to admit relearning my
group()
andorder()
semantics. Then I spent some time trying to make sure that my traversal prioritized items that were already started, as the sample gave different answers if your workers changed steps willy-nilly.Post-submission optimization: you can just step down the minimum time of the nodes being worked on instead of 1.
This is my C# solution. I'm using Advent of Code this year to practice C# so I'm sure there's lots of opportunity for improvement, but it works! I only work on these in the half hour between getting to work and my workday starting (don't ask) and sometimes at lunch, so I might fall pretty far behind after this weekend...
I quite liked this puzzle! It took me a few false starts-- I couldn't decide whether to track a step's dependencies or dependents --but ultimately I quite like the way my code turned out. Calling
sort
on every step seemed...wasteful...to me, but it was fast enough, so it all worked out in the end.Here's my Julia code (boring parsing, etc. omitted but available here)
Part 2 was also enjoyable-- I briefly considered actually spawning 5 worker threads and keeping a global clock, but then I realized I could just track how much work was being done in between tracking which nodes are now available.
PHP
ohhhhh my god this one took me a really long time for a variety of goofy reasons, mostly not understanding how things were supposed to work correctly
Part 1:
Part 2:
The last part was difficult for me! Took me some time to figure out the small details to take care of.
For now here is my Python code. I am sure it can be simplified by a lot and made much more easy to read. Hopefully I will find time to do it later.
I am building a tree to solve this problem.
I was convinced at first I could sort the steps like this:
It worked on the test data, but not on the full problem. I was really frustrated for a while, and had to google it, coming up with Kahn's algorithm
I went through an imperative, mutation-heavy version first but my Kotlin for part 1 ended up like this:
Once I got there, I found part 2 to be a fairly straightforward extension to parallelise the work and keep track of remaining time. One trick was to make the
Work
ordering put in-progress work first, so on each iterations the workers pulled active steps from the stack first.Got my Rust solution done! After banging my head on it all yesterday, I'm glad I took a break and came back fresh. It seemed to go pretty smoothly the second try at it.
Part 1
Part 2
In part 2, I'm pretty sure we just re-invented the event loop? This mega-function could probably be boiled down to helper functions, but I'm OK with this for now.