Commit Graph

49 Commits

Author SHA1 Message Date
5e91487466 Day 19 solution
Cribbed from some posts on the subreddit. I don't know why this one was so difficult for me.
2022-12-21 23:12:50 -06:00
aba8631366 Reformat code, remove unnecessary function 2022-12-21 13:27:12 -06:00
bb68e1d944 Fix Rider profiler on Windows
I don't know why, but in a Profiling run, File.Exists() returns true for a file that very much does not exist. Adding the directory check enables it to get the actually-correct answer. Another option is handling an exception in File.ReadLines, but I'm ok with this for now.

This doesn't fix Rider's profiler on macos, though...on mac, it hangs forever thinking that input is redirected but not actually having anything in the buffer. I haven't found a fix for that yet.
2022-12-21 13:26:39 -06:00
2d36c722a7 Forgot to add flavor messages here 2022-12-21 13:24:36 -06:00
e734972170 Day 21 answer
Inverting the operations gave me some trouble, but I made it.
2022-12-21 12:21:49 -06:00
52bd9dfc2b Day 20 solution
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.
2022-12-20 00:45:40 -06:00
6de69511e5 Day 16 solution
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.
2022-12-18 23:59:16 -06:00
f4e2351dbb Last day 17 improvements
Some easy tweaks from the profiler's data that move part 1 from 200ms to 10ms (both by applying some previous part 2 optimizations and also from the same changes that improved part 2 further) and part 2 from 90ms to 60ms.

I always knew LINQ was trading speed for convenience, but I'm not sure I realized just how much the trade-off costs under some circumstances. It definitely still has its value and can be "fast" or at least "fast enough" if used properly.
2022-12-18 12:31:39 -06:00
1ff595a6cd Dramatically improve day 17 runtime
This takes the time from 20s+ to 90ms. There were 2 slow places, both LINQ shortcuts I was taking to simplify a few problems. Keeping track of the current tower height can be done without finding the highest Y out of the entire tower repeatedly per rock, which was a big chunk of slowness, and finding cycles can be done without chunking things up and comparing every single chunk, which was the other part of the slowness (I can be reasonably sure that if 3 chunks in a row match, we probably found the cycle, at least with the sample input and my input).

Then a tiny amount of tuning the data to my input set (skipping 300 since it finds the loop starting at offset 309) and changing an unrolled multiplication loop into a plain multiply cleans up the last few bits.
2022-12-18 12:20:16 -06:00
818e9478e1 Day 18 solution
ivec3 is a copy of ivec2 with a third dimension added and a few new utility methods (chiefly: MinElement, GetNeighbors, IsTouching).
2022-12-18 11:11:37 -06:00
09f866c9a3 Day 17 solution
This is very slow. There are lots of ways to optimize it, but I hate this problem so I probably won't come back to it. But maybe.
2022-12-17 01:55:17 -06:00
fcfdb7146b Add ability to run multiple days from command line
Also add timing for the entire program run.
2022-12-16 08:42:13 -06:00
fdf621b58d 10x speedup on part 1
Mostly from not testing and adding each individual vector, just the x component we care about. Some of the improvement came from setting capacity on the hash set up front. I could get even better if I was smarter about computing ranges of numbers rather than this dumb approach of putting each number into a hashset to function as a union/intersection surrogate.
2022-12-15 16:13:36 -06:00
70758cf4a9 Turn ivec2 into lvec2
Or i64vec2. I expect to get hit by "huge numbers" in the very near future.
2022-12-15 15:35:52 -06:00
c935f4be4e Make immutable 2022-12-15 15:32:23 -06:00
60e2c429db Treat the vector as immutable 2022-12-15 15:05:48 -06:00
df9a0f9a6e Forgot to set this back
This was using the sample row.
2022-12-15 15:05:19 -06:00
ea72d12566 Quick perf improvement
Day 15 part 2 is now ~300ms on my PC with my dataset in Release (~1s in Debug, which is...striking).
2022-12-15 14:47:00 -06:00
e14f71484f Day 15 solution
Pretty rough, this is my initial solve. Part 2 needs to be sped up, but is currently 3 seconds on my PC and my dataset.
2022-12-15 14:12:52 -06:00
ea2626cd75 Stole @tocchan's ivec2 class
With his blessing. Ran Rider's formatter on it and tweaked a few things, but otherwise it's all his.
2022-12-15 14:12:48 -06:00
c710a86f45 Cut day 14 runtime in half
This is mostly from reusing the same object instead of creating a new one each time we test a new point, but there's also a minor amount of speedup from using HashSet instead of Dictionary. I originally thought I would need to care about why each spot was blocked (wall vs sand) but it turns out that's not important for this problem.
2022-12-14 21:49:18 -06:00
b1d57f4fd0 Day 14 solution
This runs slower than I'd like, but I wanted to check my initial solution submitted so I can iterate on it later.
2022-12-14 17:42:23 -06:00
ba6ad54329 Day 13 solution
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.
2022-12-13 17:15:16 -06:00
61227ba688 Dramatic speedup for day 12 part 2
This enables a flood-fill of distances from the goal location to every other location on the grid. With that, we only have to locate the node with the lowest distance value.

Technically this also solves part 1, but I wanted to leave the forward search in place as a test of sorts that the algorithm works both ways.

Now if I can just get the parse sped up...
2022-12-12 20:27:07 -06:00
2f73611a7c Day 12 solution
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.
2022-12-12 17:13:02 -06:00
093178376d Remove empty file 2022-12-12 13:42:19 -06:00
df362c0fd4 Day 11 solution
Prime number shenanigans...I do not like "cool math games"...
2022-12-11 10:25:12 -06:00
8aab7076fb Day 10 solution
Pretty happy with this solution. Took me longer to read and understand part 2 than I would have liked, but it's done, and pretty cleanly, too.
2022-12-10 09:25:07 -06:00
dd50a46ede Day 9 solution
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.
2022-12-08 23:38:01 -06:00
f9e75ffcad Minor restructure, .net update, add utilities 2022-12-08 22:59:46 -06:00
87ad248b3a More encoding preamble stripping fixes 2022-12-08 19:27:30 -06:00
3920a9614c Rider changes 2022-12-08 19:02:58 -06:00
34783e647e Day 8 solution
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.
2022-12-08 10:31:32 -06:00
8f9b147913 Day 7 solution
Cleaned this one up a bit after getting the solve, and did a few things to make Rider quiet.
2022-12-06 23:49:59 -06:00
a3b906f94d Day 6 solution 2022-12-05 23:28:34 -06:00
b9161e4b42 Day 5 solution
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.)
2022-12-04 23:46:24 -06:00
4b51ff9970 Day 4 solution 2022-12-04 00:47:34 -06:00
3fc0340738 Appease Rider's inspections
The list is finally clear.
2022-12-03 08:58:26 -06:00
771a21b969 Day 3 solution
Took me a bit to remember how Aggregate worked, as it always does when I need it.
2022-12-03 08:57:51 -06:00
89484e1a0a Add more files that Rider created 2022-12-01 23:14:58 -06:00
ff7633dc12 Day 2 solution
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.
2022-12-01 23:14:45 -06:00
483f1f2502 Strip more BOMs
The 01a sample text file I created in VS2022 has a big-endian utf-16 byte order mark in front. When read with File.Read* methods it was fine, but when piped in from the command line it was causing the integer parsing to fail due to the extra bytes on the front. This is the cleanest way I can find to strip any of a set of BOMs from a string. Maybe there's an easier way somewhere, but the main issue is that using something like line[0..1].SequenceEqual() may or may not use wide chars (0xFEFF as opposed to 0xFE, 0xFF, for example) so I can't just build a list of preamble arrays and check if the byte version of the string starts with them.

The "StripPreamble" character list is still a mystery. I found it while working on my Macbook for aoc2021 and can't seem to find any search results indicating what these bytes represent, so...just gonna leave it there.
2022-12-01 11:59:43 -06:00
c1757500da Sample input for day 1 2022-12-01 08:48:36 -06:00
e2c78ecc45 Day 1 solution 2022-12-01 07:17:05 -06:00
756d8e519a Don't process twice if the file exists on disk 2022-11-30 20:40:00 -06:00
22c89a7e0e Apply a few more Rider suggestions 2022-11-30 20:38:03 -06:00
55f8a1806c Embed inputs as resources
This enables the binary to be invoked from anywhere and still run on the default input set, as well as being more portable/shareable which can help with performance comparisons between machines. Files are still supported if they exist.
2022-11-30 20:37:36 -06:00
d725a9e52e Add Rider files, apply Rider suggestions 2022-11-30 17:39:40 -06:00
23945154d4 Initial commit - framework 2022-11-30 17:19:53 -06:00