Skip to content

Commit 0dee021

Browse files
committed
2 parents f188616 + cac4fe3 commit 0dee021

File tree

3 files changed

+206
-5
lines changed

3 files changed

+206
-5
lines changed

AdventOfCode/AdventOfCode.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,7 @@
3232
<ItemGroup>
3333
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
3434
</ItemGroup>
35+
<ItemGroup>
36+
<Folder Include="Solutions\Year2023\Inputs\" />
37+
</ItemGroup>
3538
</Project>

AdventOfCode/Solutions/ASolution.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ string LoadInput() {
121121
{
122122
DateTime CURRENT_EST = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Utc).AddHours(-5);
123123
if (CURRENT_EST < new DateTime(Year, 12, Day)) throw new InvalidOperationException();
124-
124+
125125
input = Program.Http.GetStringAsync(INPUT_URL).Result.Trim();
126126
File.WriteAllText(INPUT_FILEPATH, input);
127127
File.WriteAllText(DEBUGINPUT_FILEPATH, string.Empty);
@@ -144,6 +144,9 @@ string LoadInput() {
144144
catch( InvalidOperationException ) {
145145
Console.WriteLine($"Day {Day}: Cannot fetch puzzle input before given date (Eastern Standard Time).");
146146
}
147+
catch(ArgumentException e) {
148+
Console.WriteLine(e.Message);
149+
}
147150
catch
148151
{
149152
throw;

AdventOfCode/Solutions/Year2023/Day24-Solution.cs

Lines changed: 199 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,220 @@
88
using System.Security;
99
using static AdventOfCode.Solutions.Utilities;
1010
using System.Runtime.CompilerServices;
11+
using System.Numerics;
12+
using System.Net.Http.Headers;
1113

1214
namespace AdventOfCode.Solutions.Year2023
1315
{
14-
[DayInfo(24, 2023, "")]
16+
[DayInfo(24, 2023, "Never Tell Me The Odds")]
1517
class Day24 : ASolution
1618
{
19+
List<Hailstone> Hailstones = new();
20+
21+
const long min = 200000000000000L;
22+
const long max = 400000000000000L;
23+
1724
public Day24() : base()
1825
{
26+
foreach(var l in Input.SplitByNewline())
27+
{
28+
var nums = l.ExtractLongs().ToList();
1929

30+
Hailstones.Add(new(nums[0], nums[1], nums[2], nums[3], nums[4], nums[5]));
31+
}
2032
}
2133

2234
protected override object SolvePartOne()
2335
{
24-
return null;
36+
37+
long valid = 0;
38+
foreach(var combo in Hailstones.Combinations(2)) {
39+
Hailstone h1 = combo.First();
40+
Hailstone h2 = combo.Last();
41+
42+
(var x1, var y1, var z1) = (h1.X, h1.Y, h1.Z);
43+
(var x2, var y2, var z2) = (h1.p2.X, h1.p2.Y, h1.p2.Z);
44+
(var x3, var y3, var z3) = (h2.X, h2.p2.Y, h2.p2.Z) ;
45+
(var x4, var y4, var z4) = (h2.p2.X, h2.p2.Y, h2.p2.Z);
46+
47+
var xNumerator = ((x1 * y2 - y1 * x2) * (x3 - x4)) - ((x1 - x2) * (x3 * y4 - y3 * x4));
48+
var xDenominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
49+
50+
var yNumerator = ((x1 * y2 - y1 * x2) * (y3 - y4)) - ((y1 - y2) * (x3 * y4 - y3 * x4));
51+
var yDenominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
52+
53+
if (xDenominator == 0 || yDenominator == 0) continue; //Lines are parralel
54+
else
55+
{
56+
decimal xPos = (decimal)xNumerator / (decimal)xDenominator;
57+
decimal yPos = (decimal)yNumerator / (decimal)yDenominator;
58+
59+
if (min <= xPos && xPos <= max && min <= yPos && yPos <= max)
60+
{
61+
if (h1.TimeAtXYPosition(xPos, yPos) < 0 || h2.TimeAtXYPosition(xPos, yPos) < 0 )
62+
{
63+
continue; //Occurred in someones past
64+
}
65+
else
66+
{
67+
valid++;
68+
}
69+
}
70+
}
71+
}
72+
return valid;
2573
}
2674

2775
protected override object SolvePartTwo()
2876
{
29-
return null;
77+
HashSet<long> possibleXV = null;
78+
HashSet<long> possibleYV = null;
79+
HashSet<long> possibleZV = null;
80+
81+
foreach(var c in Hailstones.Combinations(2).Where(a => a.First().dX == a.Last().dX))
82+
{
83+
HashSet<long> tmp = new();
84+
long hailVelocity = (long)c.First().dX;
85+
long distanceDiff = (long)(c.Last().X - c.First().X);
86+
for(long i = -1000; i <= 1000; i++)
87+
{
88+
try
89+
{
90+
if (distanceDiff % (i - hailVelocity) == 0) tmp.Add(i);
91+
} catch (Exception e) { }
92+
}
93+
94+
95+
if(possibleXV == null)
96+
{
97+
possibleXV = new(tmp);
98+
} else
99+
{
100+
possibleXV = possibleXV.Intersect(tmp).ToHashSet<long>();
101+
}
102+
103+
if (possibleXV.Count == 1) break;
104+
}
105+
106+
foreach (var c in Hailstones.Combinations(2).Where(a => a.First().dY == a.Last().dY))
107+
{
108+
HashSet<long> tmp = new();
109+
long hailVelocity = (long)c.First().dY;
110+
long distanceDiff = (long)(c.Last().Y - c.First().Y);
111+
for (long i = -1000; i <= 1000; i++)
112+
{
113+
try
114+
{
115+
if (distanceDiff % (i - hailVelocity) == 0) tmp.Add(i);
116+
}
117+
catch (Exception e) { }
118+
}
119+
120+
121+
if (possibleYV == null)
122+
{
123+
possibleYV = new(tmp);
124+
}
125+
else
126+
{
127+
possibleYV = possibleYV.Intersect(tmp).ToHashSet<long>();
128+
}
129+
130+
if (possibleYV.Count == 1) break;
131+
}
132+
133+
foreach (var c in Hailstones.Combinations(2).Where(a => a.First().dZ == a.Last().dZ))
134+
{
135+
HashSet<long> tmp = new();
136+
long hailVelocity = (long)c.First().dZ;
137+
long distanceDiff = (long)(c.Last().Z - c.First().Z);
138+
for (long i = -1000; i <= 1000; i++)
139+
{
140+
try
141+
{
142+
if (distanceDiff % (i - hailVelocity) == 0) tmp.Add(i);
143+
}
144+
catch (Exception e) { }
145+
}
146+
147+
148+
if (possibleZV == null)
149+
{
150+
possibleZV = new(tmp);
151+
}
152+
else
153+
{
154+
possibleZV = possibleZV.Intersect(tmp).ToHashSet<long>();
155+
}
156+
157+
if (possibleZV.Count == 1) break;
158+
}
159+
160+
long dXi = possibleXV.Single();
161+
long dYi = possibleYV.Single();
162+
long dZi = possibleZV.Single();
163+
164+
Hailstone h1 = Hailstones.First();
165+
Hailstone h2 = Hailstones.Skip(10).Take(1).Single();
166+
167+
h1.dX = h1.dX - dXi;
168+
h2.dX = h2.dX - dXi;
169+
h1.dY = h1.dY - dXi;
170+
h2.dY = h2.dY - dXi;
171+
h1.dZ = h1.dZ - dXi;
172+
h2.dZ = h2.dZ - dXi;
173+
174+
175+
var slopA = (decimal)h1.dY / (decimal)h1.dX;
176+
var slopeB = (decimal)h2.dY / (decimal)h2.dX;
177+
178+
var intersectA = (decimal)h1.Y - (slopA * (decimal)h1.X);
179+
var interesectB = (decimal)h2.Y - (slopeB * (decimal)h2.X);
180+
181+
long xPos = ((long)((interesectB - intersectA) / (slopA - slopeB)));
182+
long yPos = (long)(slopA * xPos + intersectA);
183+
long time = (long)((xPos - h1.X) / h1.dX);
184+
185+
long zPos = (long)(h1.Z + (dZi * time));
186+
187+
Console.WriteLine($"{{{dXi}}}, {{{dYi}}}, {{{dZi}}}");
188+
Console.WriteLine($"{{{xPos}}}, {{{yPos}}}, {{{zPos}}}");
189+
190+
191+
return xPos+yPos+zPos;
192+
}
193+
194+
private class Hailstone
195+
{
196+
public BigInteger X;
197+
public BigInteger Y;
198+
public BigInteger Z;
199+
200+
public BigInteger dX;
201+
public BigInteger dY;
202+
public BigInteger dZ;
203+
204+
public Hailstone(long x, long y, long z, long dX, long dY, long dZ)
205+
{
206+
X = x;
207+
Y = y;
208+
Z = z;
209+
this.dX = dX;
210+
this.dY = dY;
211+
this.dZ = dZ;
212+
}
213+
214+
public (BigInteger X, BigInteger Y, BigInteger Z) PositionAtTime(long t) => (this.X + (t * dX), this.Y + (t * dY), this.Z + (t * dZ));
215+
public (BigInteger X, BigInteger Y, BigInteger Z) p2 => (X + dX, Y + dY, Z + dZ);
216+
public decimal TimeAtXYPosition(decimal x, decimal y)
217+
{
218+
if (dX != 0)
219+
{
220+
return (x - (decimal)X) / (decimal)dX;
221+
}
222+
223+
return (y - (decimal)Y) / (decimal)dY;
224+
}
30225
}
31226
}
32-
}
227+
}

0 commit comments

Comments
 (0)