AdventOfCode 2023 Day24 Part1
This commit is contained in:
160
AdventOfCode2023/Day24.cs
Normal file
160
AdventOfCode2023/Day24.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
namespace AdventOfCode2023;
|
||||
|
||||
/*
|
||||
|
||||
--- Day 24: Never Tell Me The Odds ---
|
||||
|
||||
It seems like something is going wrong with the snow-making process. Instead of forming snow, the water that's been absorbed into the air seems to be forming hail!
|
||||
|
||||
Maybe there's something you can do to break up the hailstones?
|
||||
|
||||
Due to strong, probably-magical winds, the hailstones are all flying through the air in perfectly linear trajectories. You make a note of each hailstone's position and velocity (your puzzle input). For example:
|
||||
|
||||
19, 13, 30 @ -2, 1, -2
|
||||
18, 19, 22 @ -1, -1, -2
|
||||
20, 25, 34 @ -2, -2, -4
|
||||
12, 31, 28 @ -1, -2, -1
|
||||
20, 19, 15 @ 1, -5, -3
|
||||
|
||||
Each line of text corresponds to the position and velocity of a single hailstone. The positions indicate where the hailstones are right now (at time 0). The velocities are constant and indicate exactly how far each hailstone will move in one nanosecond.
|
||||
|
||||
Each line of text uses the format px py pz @ vx vy vz. For instance, the hailstone specified by 20, 19, 15 @ 1, -5, -3 has initial X position 20, Y position 19, Z position 15, X velocity 1, Y velocity -5, and Z velocity -3. After one nanosecond, the hailstone would be at 21, 14, 12.
|
||||
|
||||
Perhaps you won't have to do anything. How likely are the hailstones to collide with each other and smash into tiny ice crystals?
|
||||
|
||||
To estimate this, consider only the X and Y axes; ignore the Z axis. Looking forward in time, how many of the hailstones' paths will intersect within a test area? (The hailstones themselves don't have to collide, just test for intersections between the paths they will trace.)
|
||||
|
||||
In this example, look for intersections that happen with an X and Y position each at least 7 and at most 27; in your actual data, you'll need to check a much larger test area. Comparing all pairs of hailstones' future paths produces the following results:
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstones' paths will cross inside the test area (at x=14.333, y=15.333).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstones' paths will cross inside the test area (at x=11.667, y=16.667).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=6.2, y=19.4).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for hailstone A.
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstones' paths are parallel; they never intersect.
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=-6, y=-5).
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for both hailstones.
|
||||
|
||||
Hailstone A: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=-2, y=3).
|
||||
|
||||
Hailstone A: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for hailstone B.
|
||||
|
||||
Hailstone A: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for both hailstones.
|
||||
|
||||
So, in this example, 2 hailstones' future paths cross inside the boundaries of the test area.
|
||||
|
||||
However, you'll need to search a much larger test area if you want to see if any hailstones might collide. Look for intersections that happen with an X and Y position each at least 200000000000000 and at most 400000000000000. Disregard the Z axis entirely.
|
||||
|
||||
Considering only the X and Y axes, check all pairs of hailstones' future paths for intersections. How many of these intersections occur within the test area?
|
||||
|
||||
|
||||
*/
|
||||
|
||||
public class Day24 : IDay
|
||||
{
|
||||
public string ResolvePart1(string[] inputs)
|
||||
{
|
||||
Hail[] hails = inputs.Select(input => new Hail(input)).ToArray();
|
||||
bool isInputData = hails.Any(h => h.Position.X > 100000);
|
||||
long min = isInputData ? 200000000000000 : 7;
|
||||
long max = isInputData ? 400000000000000 : 27;
|
||||
long count = 0;
|
||||
for (int i = 0; i < hails.Length - 1; i++)
|
||||
{
|
||||
for (int j = i + 1; j < hails.Length; j++)
|
||||
{
|
||||
(bool intersects, double s, double t, Vector3D point) = hails[i].Intersect2D(hails[j]);
|
||||
if (intersects && s > 0 && t > 0 && point.X >= min && point.X <= max && point.Y >= min && point.Y <= max)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count.ToString();
|
||||
}
|
||||
|
||||
public string ResolvePart2(string[] inputs)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public struct Vector3D
|
||||
{
|
||||
public readonly long X;
|
||||
public readonly long Y;
|
||||
public readonly long Z;
|
||||
|
||||
public Vector3D(long x, long y, long z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct Hail
|
||||
{
|
||||
public readonly Vector3D Position;
|
||||
public readonly Vector3D Velocity;
|
||||
|
||||
public Hail(string input)
|
||||
{
|
||||
string[] parts = input.Split(" @ ");
|
||||
string[] strPosition = parts[0].Split(", ");
|
||||
Position = new Vector3D(
|
||||
x: Convert.ToInt64(strPosition[0]),
|
||||
y: Convert.ToInt64(strPosition[1]),
|
||||
z: Convert.ToInt64(strPosition[2]));
|
||||
string[] strVelocity = parts[1].Split(", ");
|
||||
Velocity = new Vector3D(
|
||||
x: Convert.ToInt64(strVelocity[0]),
|
||||
y: Convert.ToInt64(strVelocity[1]),
|
||||
z: Convert.ToInt64(strVelocity[2]));
|
||||
}
|
||||
|
||||
public (bool intersects, double s, double t, Vector3D point) Intersect2D(Hail other)
|
||||
{
|
||||
long s_Div = (-other.Velocity.X * Velocity.Y + Velocity.X * other.Velocity.Y);
|
||||
if (s_Div == 0)
|
||||
{
|
||||
return (false, 0, 0, new Vector3D());
|
||||
}
|
||||
double s = (-Velocity.Y * (Position.X - other.Position.X) + Velocity.X * (Position.Y - other.Position.Y)) / (double)s_Div;
|
||||
|
||||
long t_Div = (-other.Velocity.X * Velocity.Y + Velocity.X * other.Velocity.Y);
|
||||
if (t_Div == 0)
|
||||
{
|
||||
return (false, 0, 0, new Vector3D());
|
||||
}
|
||||
double t = (other.Velocity.X * (Position.Y - other.Position.Y) - other.Velocity.Y * (Position.X - other.Position.X)) / (double)t_Div;
|
||||
|
||||
Vector3D intersection = new((long)(Position.X + t * Velocity.X), (long)(Position.Y + t * Velocity.Y), 0);
|
||||
return (true, s, t, intersection);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user