mirror of
https://github.com/parnic/advent-of-code-2022.git
synced 2025-06-16 13:40:13 -05:00
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.
This commit is contained in:
@ -81,6 +81,7 @@
|
||||
<None Remove="inputs\20.txt" />
|
||||
<EmbeddedResource Include="inputs\20.txt" />
|
||||
<None Remove="inputs\21.txt" />
|
||||
<EmbeddedResource Include="inputs\20a.txt" />
|
||||
<EmbeddedResource Include="inputs\21.txt" />
|
||||
<None Remove="inputs\22.txt" />
|
||||
<EmbeddedResource Include="inputs\22.txt" />
|
||||
|
5102
inputs/20.txt
5102
inputs/20.txt
File diff suppressed because it is too large
Load Diff
7
inputs/20a.txt
Normal file
7
inputs/20a.txt
Normal file
@ -0,0 +1,7 @@
|
||||
1
|
||||
2
|
||||
-3
|
||||
3
|
||||
-2
|
||||
0
|
||||
4
|
75
src/20.cs
Normal file
75
src/20.cs
Normal file
@ -0,0 +1,75 @@
|
||||
namespace aoc2022;
|
||||
|
||||
internal class Day20 : Day
|
||||
{
|
||||
private List<(int num, int origIdx)> nums = new();
|
||||
internal override void Parse()
|
||||
{
|
||||
foreach (var line in Util.Parsing.ReadAllLines("20"))
|
||||
{
|
||||
nums.Add((int.Parse(line), nums.Count));
|
||||
}
|
||||
}
|
||||
|
||||
private static void mix(List<(int num, int origIdx)> mixedNums, IList<(int num, int origIdx)> origNums)
|
||||
{
|
||||
for (int i = 0; i < origNums.Count; i++)
|
||||
{
|
||||
if (origNums[i].num == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var idx = mixedNums.FindIndex(n => n.origIdx == origNums[i].origIdx);
|
||||
mixedNums.RemoveAt(idx);
|
||||
var newIdx = Util.Math.Modulo(idx + origNums[i].num, mixedNums.Count);
|
||||
mixedNums.Insert((int)newIdx, origNums[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void mix(List<(long num, int origIdx)> mixedNums, IList<(long num, int origIdx)> origNums)
|
||||
{
|
||||
for (int i = 0; i < origNums.Count; i++)
|
||||
{
|
||||
if (origNums[i].num == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var idx = mixedNums.FindIndex(n => n.origIdx == origNums[i].origIdx);
|
||||
mixedNums.RemoveAt(idx);
|
||||
var newIdx = Util.Math.Modulo(idx + origNums[i].num, mixedNums.Count);
|
||||
mixedNums.Insert((int)newIdx, origNums[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal override string Part1()
|
||||
{
|
||||
var mixedNums = new List<(int num, int origIdx)>(nums);
|
||||
mix(mixedNums, nums);
|
||||
|
||||
var zeroIdx = mixedNums.FindIndex(n => n.num == 0);
|
||||
var coord1 = mixedNums[(zeroIdx + 1000) % mixedNums.Count].num;
|
||||
var coord2 = mixedNums[(zeroIdx + 2000) % mixedNums.Count].num;
|
||||
var coord3 = mixedNums[(zeroIdx + 3000) % mixedNums.Count].num;
|
||||
|
||||
return $"Grove coordinate sum: <+white>{coord1 + coord2 + coord3}";
|
||||
}
|
||||
|
||||
internal override string Part2()
|
||||
{
|
||||
var keyedNums = new List<(long num, int origIdx)>(nums.Select(c => (c.num * 811589153L, c.origIdx)));
|
||||
var mixedKeyedNums = new List<(long num, int origIdx)>(keyedNums);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
mix(mixedKeyedNums, keyedNums);
|
||||
}
|
||||
|
||||
var zeroIdx = mixedKeyedNums.FindIndex(n => n.num == 0);
|
||||
var coord1 = mixedKeyedNums[(zeroIdx + 1000) % mixedKeyedNums.Count].num;
|
||||
var coord2 = mixedKeyedNums[(zeroIdx + 2000) % mixedKeyedNums.Count].num;
|
||||
var coord3 = mixedKeyedNums[(zeroIdx + 3000) % mixedKeyedNums.Count].num;
|
||||
|
||||
return $"Fully decrypted grove coordinate sum: <+white>{coord1 + coord2 + coord3}";
|
||||
}
|
||||
}
|
@ -43,4 +43,19 @@ public static class Math
|
||||
{
|
||||
return (a * b) / GCD(a, b);
|
||||
}
|
||||
|
||||
public static long Modulo(long numer, long denom) {
|
||||
// long q = numer / denom;
|
||||
long r = numer % denom;
|
||||
if (r < 0) {
|
||||
if (denom > 0) {
|
||||
// q = q - 1;
|
||||
r = r + denom;
|
||||
} else {
|
||||
// q = q + 1;
|
||||
r = r - denom;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user