This is super slow, but it works. Talked through some speedup ideas with @tocchan that I'm going to try next.
Gonna be a BFS pro by the end of this advent...
This horrible monstrosity solves my input and probably only my input. I originally solved the sample, but didn't realize that my actual input had the cube in a different orientation. So that was about 45 minutes well spent trying to figure out the mappings of cube edges by hand. Then got stuck trying to debug the exact tile transitions from spot to spot...but I'd rather do all this than try to figure out 3d cube mapping...
Yes, I skipped day 19. For now. It sucks.
Day 20 is another "oh right, % is remainder in C#, not modulo" which means it does dumb things with negative numbers. I originally implemented this by hand, looping through the addition/subtraction and wrapping as necessary, but found "euclidean division" after a few Google searches for, essentially, "surely C# can do modulo somehow, right?" and finding that the answer is "no, not really" (though there is an open proposal to make %% a true modulo operator, but that doesn't help me now). So this math utility was the best thing I could find on Wikipedia that did what I wanted (I don't need both the division and modulo response, though, so I left the division part commented out for now). The other trick here is using the shortened length of the array when performing the modulo due to the rules around how wrapping works in this problem (which I think is terribly explained and confusing, but it's also late and I could just be dumb).
I think a faster solution is to just change indices instead of actually moving numbers around in the list, but I'm happy with this for now.
I spent an inordinately long amount of time on part 2, only to discover a fundamental flaw in my logic. Apparently for my input set, switching to the other person every time the first person had less time remaining meant that some combinations never got tested. The solution in this commit exhausts every option for one person, then every option for the second person (or animal...) which works for my test input. I have a feeling it won't work for all, though.
I am not completely happy with this data structure, but it's functional enough. I wanted to implement comparers and equality overrides for the classes to make part 2 shorter, but it would have come at the cost of a bunch of boilerplate code, so whatever.
This is quite slow, at least for part 2 (and part 1 is slower than I want it to be, event parse takes longer than I thought it should). I need a better approach to the second part. Probably need to mark all nodes' distances from the goal point instead of one-by-one plotting a path from each possible start to the end, but that requires an adjustment to how I'm building the graph in the first place.
This is ugly. I probably should've vec2'd this, made smarter move and follow logic that isn't a series of 'if's, and found a smarter way to calculate distance than my hackneyed vector distance, but it totally works so I'm rolling with it.
I'm sure there's a cleaner way to search in four directions rather than manually running each loop like this, but I didn't want to mess with genericizing it just yet.
A Deep Copy and a double-ended queue would have made this day much easier. I should add those. (Having trouble finding a generic deep copy that works in .net 6, though...I opted to rewrite my original List<List<char>> solution into List<string> in lieu of a deep copy so I wouldn't have to parse the input all over again.)
This is an ugly, kind-of-brute-force solution. I'm not proud of it, but it works and got me top 1000 on both parts.
I also changed the "which day to run if no day is specified" to just always choose the highest numbered day.