Day 7 Part1

Day 8
This commit is contained in:
2024-12-11 21:37:58 -05:00
parent 46028bee5d
commit 7739cb08a5
4 changed files with 232 additions and 7 deletions

View File

@@ -204,7 +204,6 @@ internal class GuardGallivant : Problem<int, int>
found.Add(obstaclePos); found.Add(obstaclePos);
} }
//}
} }
} }
} }
@@ -253,13 +252,13 @@ file class GuardMap
var curNode = nodes[0]; var curNode = nodes[0];
while (true) while (true)
{ {
if (curNode.Next is int nextId) if (curNode.Next is int nextId && nextId >= 0)
{ {
var next = nodes[nextId]; var next = nodes[nextId];
path.AddRange(GetPointsBetween(curNode.Pos, next.Pos, curNode.Direction).Select(p => (p, curNode))); path.AddRange(GetPointsBetween(curNode.Pos, next.Pos, curNode.Direction).Select(p => (p, curNode)));
curNode = next; curNode = next;
} }
else else if(curNode.Next == -1)
{ {
var end = curNode.Direction switch var end = curNode.Direction switch
{ {
@@ -271,7 +270,8 @@ file class GuardMap
}; };
path.AddRange(GetPointsBetween(curNode.Pos, end, curNode.Direction).Select(p => (p, curNode))); path.AddRange(GetPointsBetween(curNode.Pos, end, curNode.Direction).Select(p => (p, curNode)));
break; break;
} }else
break;
} }
return path; return path;
@@ -312,7 +312,11 @@ file class GuardMap
while (true) while (true)
{ {
if (!GetNextObstacle(curNode.Pos, curNode.Direction, out var next)) if (!GetNextObstacle(curNode.Pos, curNode.Direction, out var next))
{
curNode.Next = -1;
Nodes[curNode.Id] = curNode;
break; break;
}
var newNode = new GuardNode(next - GuardGallivant.DIRS[curNode.Direction], (curNode.Direction + 1) % 4, Nodes.Count); var newNode = new GuardNode(next - GuardGallivant.DIRS[curNode.Direction], (curNode.Direction + 1) % 4, Nodes.Count);
curNode.Next = newNode.Id; curNode.Next = newNode.Id;
Nodes[curNode.Id] = curNode; Nodes[curNode.Id] = curNode;

View File

@@ -5,6 +5,70 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2024.Day7; namespace AdventOfCode.Problems.AOC2024.Day7;
internal class BridgeRepair
[ProblemInfo(2024, 7, "Bridge Repair")]
internal class BridgeRepair : Problem<ulong, ulong>
{ {
} private List<(ulong total, ulong[] nums)> _data = [];
private enum Operator
{
Mul,
Add,
Concat
}
public override void CalculatePart1()
{
foreach (var (target, nums) in _data)
{
if (IsSolvable(target, nums, [Operator.Mul, Operator.Add]))
Part1 += target;
}
}
private bool IsSolvable(ulong target, ulong[] nums, Operator[] ops)
{
return ops.Any(o => IsSolvable(target, nums, o, nums[0], ops));
}
private bool IsSolvable(ulong target, ulong[] nums, Operator curOperator, ulong curTotal, Operator[] ops, int idx = 1)
{
if (target == curTotal)
return true;
if (idx >= nums.Length)
return false;
curTotal = curOperator switch
{
Operator.Mul => curTotal * nums[idx++],
Operator.Add => curTotal + nums[idx++],
Operator.Concat => ulong.Parse($"{curTotal}{nums[idx++]}"),
_ => curTotal,
};
return ops.Any(o => IsSolvable(target, nums, o, curTotal, ops, idx));
}
public override void CalculatePart2()
{
foreach (var (target, nums) in _data)
{
if (IsSolvable(target, nums, [Operator.Mul, Operator.Add, Operator.Concat]))
Part2 += target;
}
}
public override void LoadInput()
{
var lines = ReadInputLines("input.txt");
_data = new List<(ulong total, ulong[] nums)>(lines.Length);
foreach (var line in lines)
{
var s = line.Split(':');
var sum = ulong.Parse(s[0].Trim());
var nums = s[1].Trim().Split(' ').Select(ulong.Parse).ToArray();
_data.Add((sum, nums));
}
}
}

View File

@@ -0,0 +1,139 @@
using AdventOfCode.Utils.Models;
using System.Collections.Frozen;
namespace AdventOfCode.Problems.AOC2024.Day8;
[ProblemInfo(2024, 8, "Resonant Collinearity")]
internal class ResonantCollinearity : Problem<int, int>
{
private string[] _map = [];
private int _width;
private int _height;
private FrozenDictionary<char, List<Vec2<int>>> _nodes = FrozenDictionary<char, List<Vec2<int>>>.Empty;
public override void CalculatePart1()
{
var antiNodes = new List<Vec2<int>>();
foreach (var (nodeType, nodes) in _nodes)
{
foreach (var a in nodes)
{
foreach (var b in nodes)
{
if (a == b)
continue;
antiNodes.AddRange(GetAntiNodes(a, b));
}
}
}
//PrintBoard(antiNodes);
Part1 = antiNodes.Where(IsInBounds).Distinct().Count();
}
public void PrintBoard(List<Vec2<int>> antinodes)
{
Console.WriteLine();
for (int y = 0; y < _height; y++)
{
for (int x = 0; x < _width; x++)
{
Console.ResetColor();
var p = new Vec2<int>(x, y);
if (antinodes.Contains(p))
Console.BackgroundColor = ConsoleColor.DarkGreen;
Console.Write(_map[y][x]);
}
Console.ResetColor();
Console.WriteLine();
}
Console.ResetColor();
}
public bool IsInBounds(Vec2<int> pos)
{
if (pos.X < 0 || pos.Y < 0)
return false;
if (pos.X >= _width || pos.Y >= _height)
return false;
return true;
}
private Vec2<int>[] GetAntiNodes(Vec2<int> a, Vec2<int> b)
{
var dir = a - b;
var aNode1 = dir + a;
var aNode2 = -dir + b;
return [aNode1, aNode2];
}
private Vec2<int>[] GetHarmonicAntiNodes(Vec2<int> a, Vec2<int> b)
{
var dir = a - b;
List<Vec2<int>> GetNodes(Vec2<int> start, Vec2<int> dir)
{
var results = new List<Vec2<int>>();
while (true)
{
var p = dir + start;
if(!IsInBounds(p))
break;
results.Add(p);
start = p;
}
return results;
}
return [.. GetNodes(a, dir), .. GetNodes(b, -dir)];
}
public override void CalculatePart2()
{
var antiNodes = new List<Vec2<int>>();
foreach (var (nodeType, nodes) in _nodes)
{
foreach (var a in nodes)
{
foreach (var b in nodes)
{
if (a == b)
continue;
antiNodes.AddRange(GetHarmonicAntiNodes(a, b));
}
}
}
//PrintBoard(antiNodes);
antiNodes.AddRange(_nodes.Values.Where(v => v.Count > 1).SelectMany(v => v));
Part2 = antiNodes.Distinct().Count();
}
public override void LoadInput()
{
_map = ReadInputLines("input.txt");
var nodes = new Dictionary<char, List<Vec2<int>>>();
_width = _map[0].Length;
_height = _map.Length;
for (int y = 0; y < _map.Length; y++)
{
var row = _map[y];
for (int x = 0; x < row.Length; x++)
{
switch (row[x])
{
case '.':
continue;
default:
var p = new Vec2<int>(x, y);
if (!nodes.TryAdd(row[x], [p]))
nodes[row[x]].Add(p);
continue;
}
}
}
_nodes = nodes.ToFrozenDictionary();
}
}

View File

@@ -2,19 +2,37 @@
namespace AdventOfCode.Utils.Models; namespace AdventOfCode.Utils.Models;
public record struct Vec2<T>(T X, T Y) where T : INumber<T> public record struct Vec2<T>(T X, T Y) where T : INumber<T>
{ {
public static Vec2<T> operator +(Vec2<T> left, Vec2<T> right) => new Vec2<T>(left.X + right.X, left.Y + right.Y); public static Vec2<T> operator +(Vec2<T> left, Vec2<T> right) => new Vec2<T>(left.X + right.X, left.Y + right.Y);
public static Vec2<T> operator -(Vec2<T> left, Vec2<T> right) => new Vec2<T>(left.X - right.X, left.Y - right.Y); public static Vec2<T> operator -(Vec2<T> left, Vec2<T> right) => new Vec2<T>(left.X - right.X, left.Y - right.Y);
public static Vec2<T> operator -(Vec2<T> vec) => new Vec2<T>(-vec.X, -vec.Y);
public static Vec2<T> operator *(Vec2<T> left, T right) => new Vec2<T>(left.X * right, left.Y * right); public static Vec2<T> operator *(Vec2<T> left, T right) => new Vec2<T>(left.X * right, left.Y * right);
public static Vec2<T> operator *(T left, Vec2<T> right) => new Vec2<T>(right.X * left, right.Y * left);
public static Vec2<T> operator /(Vec2<T> left, T right) => new Vec2<T>(left.X / right, left.Y / right); public static Vec2<T> operator /(Vec2<T> left, T right) => new Vec2<T>(left.X / right, left.Y / right);
public T DistanceSq(Vec2<T> other)
{
var a = other.X - this.X;
var b = other.Y - this.Y;
return (a * a) + (b * b);
}
} }
public record struct Vec3<T>(T X, T Y, T Z) where T : INumber<T> public record struct Vec3<T>(T X, T Y, T Z) where T : INumber<T>
{ {
public static Vec3<T> operator +(Vec3<T> left, Vec3<T> right) => new Vec3<T>(left.X + right.X, left.Y + right.Y, left.Z + right.Z); public static Vec3<T> operator +(Vec3<T> left, Vec3<T> right) => new Vec3<T>(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
public static Vec3<T> operator -(Vec3<T> left, Vec3<T> right) => new Vec3<T>(left.X - right.X, left.Y - right.Y, left.Z - right.Z); public static Vec3<T> operator -(Vec3<T> left, Vec3<T> right) => new Vec3<T>(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
public static Vec3<T> operator -(Vec3<T> vec) => new Vec3<T>(-vec.X, -vec.Y, -vec.Z);
public static Vec3<T> operator *(Vec3<T> left, T right) => new Vec3<T>(left.X * right, left.Y * right, left.Z * right); public static Vec3<T> operator *(Vec3<T> left, T right) => new Vec3<T>(left.X * right, left.Y * right, left.Z * right);
public static Vec3<T> operator *(T left, Vec3<T> right) => new Vec3<T>(right.X * left, right.Y * left, right.Z * left);
public static Vec3<T> operator /(Vec3<T> left, T right) => new Vec3<T>(left.X / right, left.Y / right, left.Z / right); public static Vec3<T> operator /(Vec3<T> left, T right) => new Vec3<T>(left.X / right, left.Y / right, left.Z / right);
public T DistanceSq(Vec3<T> other)
{
var a = other.X - this.X;
var b = other.Y - this.Y;
var c = other.Z - this.Z;
return (a * a) + (b * b) + (c * c);
}
} }