Compare commits

..

4 Commits

Author SHA1 Message Date
f229802a6b day 10 part 2 wip 2026-01-04 12:48:48 -05:00
4b7eee6b24 day 10 part 1 2026-01-04 00:01:19 -05:00
2d7e0f9c15 no idea what i'm doing 2026-01-01 11:17:34 -05:00
7564a3627f day 4 part 2 2025-12-30 18:56:25 -05:00
5 changed files with 279 additions and 58 deletions

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AdventOfCode.Problems.AOC2025.Day10;
[ProblemInfo(2025, 10, "Factory")]
internal class Factory : Problem<int, int>
{
private List<Machine> _data = [];
public override void CalculatePart1()
{
var results = new int[_data.Count];
Parallel.ForEach(_data, (m, _, i) => results[i] = m.SolveLights());
Part1 = results.Sum();
}
public override void CalculatePart2()
{
var results = new int[_data.Count];
Parallel.ForEach(_data, (m, _, i) => results[i] = m.SolveJoltage());
Part2 = results.Sum();
}
public override void LoadInput()
{
_data = ReadInputLines("input.txt").Select(l => new Machine(l)).ToList();
}
public class Machine
{
public bool[] Target { get; private set; }
public int[][] Operations { get; private set; }
public int[] Requirements { get; private set; }
public Machine(string data)
{
var sections = data.Split(' ');
Target = sections[0][1..^1].Select(c => c == '.' ? false : true).ToArray();
Operations = sections[1..^1].Select(op => op[1..^1])
.Select(op => op.Split(',').Select(int.Parse).ToArray())
.ToArray();
Requirements = sections[^1][1..^1].Split(',').Select(int.Parse).ToArray();
}
public int SolveLights()
{
var state = Enumerable.Repeat(false, Target.Length).ToArray();
var best = Target.Length;
return Solve(Target, Operations, state, ref best);
static int Solve(bool[] goal, int[][] operations, bool[] curState, ref int best, int depth = 0)
{
static bool IsSolved(bool[] goal, bool[] state)
{
for (int i = 0; i < goal.Length; i++)
{
if (goal[i] != state[i])
return false;
}
return true;
}
if (IsSolved(goal, curState))
return depth;
if (depth >= best)
return depth;
var opCount = int.MaxValue;
foreach (var op in operations)
{
var state = new bool[curState.Length];
Buffer.BlockCopy(curState, 0, state, 0, curState.Length);
foreach (var idx in op)
state[idx] = !curState[idx];
var c = Solve(goal, operations, state, ref best, depth + 1);
if (c < best)
best = c;
if (c < opCount)
opCount = c;
}
return opCount;
}
}
public int SolveJoltage()
{
var state = new int[Requirements.Length];
var best = int.MaxValue;
return Solve(Requirements, Operations, state, ref best);
static int Solve(int[] target, int[][] operations, int[] curState, ref int best, int depth = 0)
{
if (depth > best)
return int.MaxValue;
if (IsOver(target, curState))
return int.MaxValue;
if (IsSolved(target, curState))
{
if (depth < best)
best = depth;
return depth;
}
static bool IsOver(int[] target, int[] curState)
{
for (int i = 0; i < target.Length; i++)
{
if (target[i] < curState[i])
return true;
}
return false;
}
static bool IsSolved(int[] target, int[] curState)
{
for (int i = 0; i < target.Length; i++)
{
if (target[i] != curState[i])
return false;
}
return true;
}
var opCount = int.MaxValue;
foreach (var op in operations)
{
var state = new int[curState.Length];
Buffer.BlockCopy(curState, 0, state, 0, curState.Length * sizeof(int));
foreach (var idx in op)
state[idx] += 1;
var c = Solve(target, operations, state, ref best, depth + 1);
if (c < opCount)
opCount = c;
}
return opCount;
}
}
}
}

View File

@@ -1,6 +1,7 @@
using AdventOfCode.Utils.Models;
using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Text;
@@ -13,36 +14,23 @@ internal class PrintingDeparment: Problem<int, int>
public override void CalculatePart1()
{
var c = 0;
for (int y = 0; y < _size.Y; y++)
{
for (int x = 0; x < _size.X; x++)
{
var pos = new Vec2<int>(x, y);
if (_data[pos.Y][pos.X] != '@')
continue;
var n = CountNeighbors(pos);
if (n < 4)
c++;
}
}
Part1 = c;
Part1 = GetAccessableRolls(_data, _size).Count;
}
public int CountNeighbors(Vec2<int> pos)
public static int CountNeighbors(string[] data, Vec2<int> size, Vec2<int> pos)
{
var c = 0;
for (int y = pos.Y-1; y <= pos.Y + 1; y++)
{
if (y < 0 || y >= _size.Y)
if (y < 0 || y >= size.Y)
continue;
for (int x = pos.X - 1; x <= pos.X + 1; x++)
{
if (x < 0 || x >= _size.X)
if (x < 0 || x >= size.X)
continue;
if (pos.X == x && pos.Y == y)
continue;
if (_data[y][x] == '@')
if (data[y][x] == '@')
c++;
}
}
@@ -51,7 +39,50 @@ internal class PrintingDeparment: Problem<int, int>
public override void CalculatePart2()
{
throw new NotImplementedException();
var data = _data;
var rolls = GetAccessableRolls(data, _size);
Part2 += rolls.Count;
while(rolls.Count > 0)
{
data = RemoveRolls(data, _size, rolls);
rolls = GetAccessableRolls(data, _size);
Part2 += rolls.Count;
}
}
public static List<Vec2<int>> GetAccessableRolls(string[] data, Vec2<int> size)
{
var results = new List<Vec2<int>>();
for (int y = 0; y < size.Y; y++)
{
for (int x = 0; x < size.X; x++)
{
var pos = new Vec2<int>(x, y);
if (data[pos.Y][pos.X] != '@')
continue;
var n = CountNeighbors(data, size, pos);
if (n < 4)
results.Add(pos);
}
}
return results;
}
public static string[] RemoveRolls(string[] data, Vec2<int> size, List<Vec2<int>> rolls)
{
var positions = rolls.ToFrozenSet();
return data.Select((row, y) =>
{
var updatedRow = row.Select((col, x) =>
{
var pos = new Vec2<int>(x, y);
if (positions.Contains(pos))
return '.';
else
return col;
}).ToArray();
return new string(updatedRow);
}).ToArray();
}
public override void LoadInput()

View File

@@ -9,49 +9,42 @@ namespace AdventOfCode.Problems.AOC2025.Day8;
[ProblemInfo(2025, 8, "Playground")]
internal class Playground : Problem<long, long>
{
private Vec3<int>[] _boxPositions= [];
private Vec3i[] _boxPositions= [];
public override void CalculatePart1()
{
var boxes = _boxPositions.Select((p, i) => new JunctionBox(i, p, [])).ToArray();
var networks = new List<Network>();
var closest = GetClosestPairs(_boxPositions, 1000);
foreach (var (a, b)in closest)
{
var boxA = boxes.First(box => box.Pos == a);
var boxB = boxes.First(box => box.Pos == b);
boxA.Connections.Add(boxB.Id);
boxB.Connections.Add(boxA.Id);
var existingNetworkA = networks.FirstOrDefault(n => n.Members.Contains(a));
var existingNetworkB = networks.FirstOrDefault(n => n.Members.Contains(b));
if ((existingNetworkA != null && existingNetworkB == null))
existingNetworkA.AddConnection(a, b);
else if (existingNetworkB != null && existingNetworkA == null)
existingNetworkB.AddConnection(a, b);
else if (existingNetworkA != null && existingNetworkB != null && existingNetworkA != existingNetworkB)
{
existingNetworkA.AddConnection(a, b);
existingNetworkA.MergeWith(existingNetworkB);
networks.Remove(existingNetworkB);
}
else if(existingNetworkA == null && existingNetworkB == null)
{
var newNetwork = new Network().AddConnection(a, b);
networks.Add(newNetwork);
}
}
var networks = TraceNetworks(boxes);
Part1 = networks.Select(n => (long)n.Count).OrderDescending().Take(3).Aggregate((a, b) => a * b);
Console.WriteLine($"Networks: {networks.Count}");
Part1 = networks.Select(n => n.Members.Count)
.OrderDescending()
.Take(3)
.Aggregate((a, b) => a * b);
}
private static List<HashSet<int>> TraceNetworks(JunctionBox[] junctionBoxes)
private static List<(Vec3i a , Vec3i b)> GetClosestPairs(Vec3i[] boxes, int count = 10)
{
var networks = new List<HashSet<int>>();
foreach (var box in junctionBoxes)
{
if (networks.Any(n => n.Contains(box.Id)))
continue;
var net = new HashSet<int>() { box.Id };
TraceJunction(box, junctionBoxes, net);
networks.Add(net);
}
return networks;//.Where(n => n.Count > 0).ToList();
}
private static void TraceJunction(JunctionBox box, JunctionBox[] boxes, HashSet<int> result)
{
foreach (var connection in box.Connections)
{
if (result.Add(connection))
TraceJunction(boxes[connection], boxes, result);
}
}
private static List<(Vec3<int> a , Vec3<int> b)> GetClosestPairs(Vec3<int>[] boxes, int count = 10)
{
var distances = new Dictionary<(Vec3<int> a, Vec3<int> b), double>();
var distances = new Dictionary<(Vec3i a, Vec3i b), double>();
for (int i = 0; i < boxes.Length; i++)
{
@@ -74,11 +67,63 @@ internal class Playground : Problem<long, long>
public override void LoadInput()
{
_boxPositions = ReadInputLines("input.txt")
_boxPositions = ReadInputLines("sample.txt")
.Select(l => l.Split(',').Select(int.Parse))
.Select(c => new Vec3<int>(c.First(), c.Skip(1).First(), c.Last()))
.Select(c => new Vec3i(c.First(), c.Skip(1).First(), c.Last()))
.ToArray();
}
private record class JunctionBox(int Id, Vec3<int> Pos, HashSet<int> Connections);
private record class JunctionBox(Vec3i Pos, HashSet<Vec3i> Connections);
private class Network
{
public HashSet<Vec3i> Members { get; private set; } = [];
public List<JunctionBox> Boxes { get; private set; } = [];
public bool IsConnectedTo(Vec3i pos)
{
return Members.Contains(pos);
}
public bool IntersectsWith(Network other)
{
return Members.Intersect(other.Members).Any();
}
public Network AddConnection(Vec3i a, Vec3i b)
{
if (Members.Contains(a) && Members.Contains(b))
return this;
Members.Add(a);
Members.Add(b);
var boxA = GetOrAddBox(a);
var boxB = GetOrAddBox(b);
boxA.Connections.Add(b);
boxB.Connections.Add(a);
return this;
}
private JunctionBox GetOrAddBox(Vec3i pos)
{
var box = Boxes.FirstOrDefault(box => box.Pos == pos);
if(box == null)
{
box = new JunctionBox(pos, []);
Boxes.Add(box);
}
return box;
}
public Network MergeWith(Network other)
{
foreach (var box in other.Boxes)
{
foreach (var connection in box.Connections)
{
AddConnection(box.Pos, connection);
}
}
return this;
}
}
}

View File

@@ -4,4 +4,4 @@ global using AdventOfCode.Utils;
var runner = new AOCRunner();
runner.WithDay(8).RenderInteractiveMenu();
runner.RenderInteractiveMenu();

View File

@@ -1,4 +1,10 @@
using System.Numerics;
global using Vec3i = AdventOfCode.Utils.Models.Vec3<int>;
global using Vec2i = AdventOfCode.Utils.Models.Vec2<int>;
global using Vec3l = AdventOfCode.Utils.Models.Vec3<long>;
global using Vec2l = AdventOfCode.Utils.Models.Vec2<long>;
global using Vec3f = AdventOfCode.Utils.Models.Vec3<float>;
global using Vec2f = AdventOfCode.Utils.Models.Vec2<float>;
using System.Numerics;
namespace AdventOfCode.Utils.Models;
@@ -65,7 +71,7 @@ public record struct Vec3<T>(T X, T Y, T Z) where T : INumber<T>
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);
return T.Abs((a * a) + (b * b) + (c * c));
}
public readonly Vec3<T> Min(Vec3<T> other) => new(T.Min(X, other.X), T.Min(Y, other.Y), T.Min(Z, other.Z));