Compare commits

...

7 Commits

Author SHA1 Message Date
5f45853889 misc 2025-12-06 21:29:45 -05:00
55a8ea0281 day 6 2025-12-06 21:13:53 -05:00
e56befa18b day 5 2025-12-05 20:00:59 -05:00
9f1a2d2300 day 4 pt 1 2025-12-04 12:58:34 -05:00
a0c97e4b75 day 2 pt 1; day 3 2025-12-03 20:29:39 -05:00
629b13abef wip day 2 2025-12-02 19:58:33 -05:00
4f4ccf7117 optimized day 1 2025-12-02 18:05:45 -05:00
12 changed files with 456 additions and 18 deletions

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@@ -11,6 +11,8 @@ namespace AdventOfCode.Problems.AOC2025.Day1;
[ProblemInfo(2025, 1, "Secret Entrance")]
internal class SecretEntrance : Problem<int, int>
{
public const int LOCK_SIZE = 100;
public int[] Input { get; set; } = [];
public override void CalculatePart1()
{
@@ -19,7 +21,7 @@ internal class SecretEntrance : Problem<int, int>
foreach (var item in Input)
{
v += item;
v = v.Mod(100);
v = v.Mod(LOCK_SIZE);
if (v == 0)
c++;
}
@@ -32,14 +34,20 @@ internal class SecretEntrance : Problem<int, int>
var v = 50;
foreach (var item in Input)
{
var sign = int.Sign(item);
for (int i = 0; i < Math.Abs(item); i++)
var vStart = v;
v += item;
if (item > 0)
c += (int)Math.Floor(v / (float)LOCK_SIZE);
else
{
v += sign;
v = v.Mod(100);
if (v == 0)
c++;
var d = v / (float)LOCK_SIZE;
var fl = Math.Floor(d);
c += (int)Math.Abs(fl) - (vStart == 0 ? 1 : 0);
if (fl == d)
c += 1;
}
v = v.Mod(LOCK_SIZE);
}
Part2 = c;
}

View File

@@ -0,0 +1,8 @@
[-100]: 1 | start: 50 v: 50
[100]: 1 | start: 50 v: 50
[-150]: 2 | start: 50 v: 0
[150]: 1 | start: 0 v: 50
[-500]: 5 | start: 50 v: 50
[500]: 5 | start: 50 v: 50
[-550]: 6 | start: 50 v: 0
[550]: 5 | start: 0 v: 5

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Text;
using ZLinq;
namespace AdventOfCode.Problems.AOC2025.Day2;
[ProblemInfo(2025, 2, "Gift Shop")]
internal class GiftShop : Problem<long, long>
{
private IdRange[] _ranges = [];
public override void CalculatePart1()
{
var v = _ranges.SelectMany(GetDoubleSequences);
//Console.WriteLine(v.AsJoinedString());
Part1 = v.Sum();
}
public static long[] GetDoubleSequences(IdRange range)
{
range = range.Snap();
var minDigits = range.Min.DigitCount() / 2;
var maxDigits = range.Max.DigitCount() / 2;
var min = GetMinValue((int)minDigits, range.Min);
var max = GetMaxValue((int)maxDigits, range.Max);
//Console.WriteLine($"{min}-{max}");
if (max < min)
return [];
var n = (max - min) + 1;
var result = new long[n];
for (long i = min; i <= max; i++)
{
result[i - min] = (i * QuickMath.FastPow10(minDigits)) + i;
}
return result;
}
public static long SnapToUpNearestValidRange(long value)
{
var dc = value.DigitCount();
if (dc.IsEven())
return value;
return QuickMath.FastPow10(dc);
}
public static long SnapToDownNearestValidRange(long value)
{
var dc = value.DigitCount();
if (dc.IsEven())
return value;
return QuickMath.FastPow10(dc - 1) - 1;
}
public static long GetMinValue(int digits, long value)
{
var val = long.Parse(value.ToString()[..^digits]);
while ((val * QuickMath.FastPow10(digits)) + val < value)
{
val++;
}
return val;
}
public static long GetMaxValue(int digits, long value)
{
var val = long.Parse(value.ToString()[..^digits]);
while ((val * QuickMath.FastPow10(digits)) + val > value)
{
val--;
}
return val;
}
public override void CalculatePart2()
{
throw new NotImplementedException();
}
public override void LoadInput()
{
var text = ReadInputText("input.txt");
_ranges = text.Split(',')
.AsValueEnumerable()
.Select(r => r.Split('-').Select(long.Parse))
.Select(r => new IdRange(r.First(), r.Last()))
.ToArray();
}
public record IdRange(long Min, long Max)
{
public IdRange Snap()
{
return new IdRange(SnapToUpNearestValidRange(Min), SnapToDownNearestValidRange(Max));
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZLinq;
namespace AdventOfCode.Problems.AOC2025.Day3;
[ProblemInfo(2025, 3, "Lobby")]
internal class Lobby : Problem<long, long>
{
private (int val, int idx)[][] _batteryBanks = [];
public override void CalculatePart1()
{
Part1 = _batteryBanks.AsValueEnumerable().Select(bank =>
{
var batteries = GetViableBatteries(bank);
return GetPower(batteries);
}).Sum();
}
public override void CalculatePart2()
{
Console.WriteLine();
var b = _batteryBanks.AsValueEnumerable().Select(bank =>
{
var batteries = GetViableBatteries(bank, 12);
return GetPower(batteries);
});
Part2 = b.Sum();
}
public static long GetPower(int[] values)
{
return values.Select((v, idx) =>
{
var mag = (long)Math.Pow(10, values.Length - idx - 1);
return v * mag;
}).Sum();
}
public static int[] GetViableBatteries((int val, int idx)[] source, int count = 2)
{
var batteries = new int[count];
var offset = 0;
for (int i = count; i > 0; i--)
{
var tgt = i - 1;
var (val, idx) = source[offset..^tgt].MaxBy(v => v.val);
offset = idx + 1;
batteries[count - i] = val;
}
return batteries;
}
public override void LoadInput()
{
_batteryBanks = ReadInputLines("input.txt")
.AsValueEnumerable()
.Select(l => l.AsValueEnumerable().Select((v, idx) => (v - '0', idx)).ToArray())
.ToArray();
}
}

View File

@@ -0,0 +1,62 @@
using AdventOfCode.Utils.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace AdventOfCode.Problems.AOC2025.Day4;
[ProblemInfo(2025, 4, "Printing Department")]
internal class PrintingDeparment: Problem<int, int>
{
private string[] _data = [];
private Vec2<int> _size;
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;
}
public int CountNeighbors(Vec2<int> pos)
{
var c = 0;
for (int y = pos.Y-1; y <= pos.Y + 1; 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)
continue;
if (pos.X == x && pos.Y == y)
continue;
if (_data[y][x] == '@')
c++;
}
}
return c;
}
public override void CalculatePart2()
{
throw new NotImplementedException();
}
public override void LoadInput()
{
_data = ReadInputLines("input.txt");
_size = new Vec2<int>(_data[0].Length, _data.Length);
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZLinq;
namespace AdventOfCode.Problems.AOC2025.Day5;
[ProblemInfo(2025, 5, "Cafeteria")]
internal class Cafeteria : Problem<long, long>
{
private (long start, long end)[] _ranges = [];
private long[] _values = [];
public override void CalculatePart1()
{
Part1 = _values.AsValueEnumerable().Count(v => _ranges.AsValueEnumerable().Any(r => IsInRange(r, v)));
}
public static bool IsInRange((long start, long end) range, long value)
{
return (range.start <= value && range.end >= value);
}
public override void CalculatePart2()
{
var merged = MergeRanges(_ranges);
merged.Print();
Console.WriteLine("----");
MergeRanges(merged.ToArray()).Print();
//merged.Print();
Part2 = merged.Select(r => r.end - r.start + 1).Sum();
}
public static List<(long start, long end)> MergeRanges((long start, long end)[] ranges)
{
var result = new List<(long start, long end)>(ranges.Length);
var used = new HashSet<int>();
for (int i = 0; i < ranges.Length; i++)
{
if (used.Contains(i))
continue;
var range = ranges[i];
for (int j = (i + 1); j < ranges.Length; j++)
{
if (used.Contains(j))
continue;
var range2 = ranges[j];
if(IsOverlapping(range, range2))
{
range = Merge(range, range2);
used.Add(j);
j = i;
}
}
result.Add(range);
}
return result;
}
public static bool IsOverlapping((long start, long end) a, (long start, long end) b)
{
return IsInRange(a, b.start) || IsInRange(a, b.end) || IsInRange(b, a.start) || IsInRange(b, a.end);
}
public static (long start, long end) Merge((long start, long end) a, (long start, long end) b)
{
return (a.start.Min(b.start), a.end.Max(b.end));
}
public override void LoadInput()
{
var lines = ReadInputLines("input.txt");
_ranges = lines
.TakeWhile(l => !string.IsNullOrWhiteSpace(l))
.Select(l => l.Split('-').Select(long.Parse))
.Select(v => (start: v.First(), end: v.Last()))
.ToArray();
_values = lines[(_ranges.Length + 1)..]
.Select(long.Parse)
.ToArray();
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace AdventOfCode.Problems.AOC2025.Day6;
[ProblemInfo(2025, 6, "Trash Compactor")]
public partial class TrashCompactor : Problem<long, long>
{
private long[][] _values = [];
private string[] _operators = [];
private IEnumerable<(char op, long[] values)> _part2Data = [];
public override void CalculatePart1()
{
for (int i = 0; i < _operators.Length; i++)
{
var op = _operators[i];
var col = _values.Select(r => r[i]).ToArray();
Part1 += op switch
{
"+" => col.Aggregate((a, b) => a + b),
"*" => col.Aggregate((a, b) => a * b),
_ => throw new InvalidOperationException()
};
}
}
public override void CalculatePart2()
{
foreach (var (op, values) in _part2Data)
{
Part2 += op switch
{
'+' => values.Aggregate((a, b) => a + b),
'*' => values.Aggregate((a, b) => a * b),
_ => throw new InvalidOperationException()
};
}
}
public override void LoadInput()
{
var lines = ReadInputLines("input.txt");
ParsePart1(lines);
ParsePart2(lines);
}
private void ParsePart1(string[] lines)
{
_values = lines[..^1].Select(l => LineMatch().Matches(l).Select(v => long.Parse(v.Value)).ToArray()).ToArray();
_operators = LineMatch().Matches(lines[^1]).Select(v => v.Value).ToArray();
}
private void ParsePart2(string[] lines)
{
var valueLines = lines[..^1];
var opLines = lines[^1];
var opPos = 0;
var len = 1;
var data = new List<(char op, string[] values)>();
for (int i = 1; i < opLines.Length; i++)
{
var curChar = opLines[i];
if (curChar != ' ' || i == opLines.Length - 1)
{
if (i == opLines.Length - 1)
len = opLines.Length - opPos + 1;
var op = opLines[opPos];
var values = valueLines.Select(v => v[opPos..(opPos + len - 1)]).ToArray();
data.Add((op, values));
len = 1;
opPos = i;
}
else
len++;
}
_part2Data = data.Select(v => (v.op, v.values.Transpose().Select(long.Parse).ToArray()));
}
[GeneratedRegex(@"(\S+)")]
private static partial Regex LineMatch();
}

View File

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

View File

@@ -34,4 +34,24 @@ public static class ExtraMath
{
return T.Min(a, b);
}
public static T Mod<T>(this T value, T divisor) where T : INumber<T>
{
T remainder = value % divisor;
if (remainder < T.Zero)
return remainder + divisor;
else
return remainder;
}
public static bool IsEven<T>(this T value) where T : INumber<T>
{
return T.IsEvenInteger(value);
}
public static bool IsOdd<T>(this T value) where T : INumber<T>
{
return T.IsOddInteger(value);
}
}

View File

@@ -13,13 +13,5 @@ public static class Extensions
return string.Join(delim, data);
}
public static T Mod<T>(this T value, T divisor) where T : INumber<T>
{
T remainder = value % divisor;
if (remainder < T.Zero)
return remainder + divisor;
else
return remainder;
}
}

View File

@@ -24,6 +24,11 @@ public record struct Vec2<T>(T X, T Y) where T : INumber<T>
var b = other.Y - this.Y;
return (a * a) + (b * b);
}
public override string ToString()
{
return $"({X}, {Y})";
}
}
public record struct Vec3<T>(T X, T Y, T Z) where T : INumber<T>
@@ -45,4 +50,9 @@ public record struct Vec3<T>(T X, T Y, T Z) where T : INumber<T>
var c = other.Z - this.Z;
return (a * a) + (b * b) + (c * c);
}
public override string ToString()
{
return $"({X}, {Y}, {Z})";
}
}