Enable running all days at once

I'm kinda bored and wanted to.
This commit is contained in:
2021-12-12 15:28:41 -06:00
parent 5c37fc4129
commit 9e7942a35e
15 changed files with 845 additions and 848 deletions

View File

@ -0,0 +1,11 @@
{
"profiles": {
"All": {
"commandName": "Project",
"commandLineArgs": "all"
},
"Default day": {
"commandName": "Project"
}
}
}

107
src/01.cs
View File

@ -1,70 +1,69 @@
namespace aoc2021
namespace aoc2021;
internal class Day01 : Day
{
internal class Day01
internal override void Go()
{
internal static void Go()
Logger.Log("Day 1");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/01.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
}
private static void Part1(IEnumerable<string> lines)
{
using var t = new Timer();
int lastDepth = 0;
int numIncreased = -1;
foreach (var line in lines)
{
Logger.Log("Day 1");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/01.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
}
private static void Part1(IEnumerable<string> lines)
{
using var t = new Timer();
int lastDepth = 0;
int numIncreased = -1;
foreach (var line in lines)
var depth = Convert.ToInt32(line);
if (depth > lastDepth)
{
var depth = Convert.ToInt32(line);
if (depth > lastDepth)
{
numIncreased++;
}
lastDepth = depth;
numIncreased++;
}
Logger.Log($"part1: {numIncreased}");
lastDepth = depth;
}
private static void Part2(IEnumerable<string> lines)
Logger.Log($"part1: {numIncreased}");
}
private static void Part2(IEnumerable<string> lines)
{
using var t = new Timer();
int lastTotal = 0;
int numIncreased = -1;
int num1 = -1;
int num2 = -1;
int num3 = -1;
foreach (var line in lines)
{
using var t = new Timer();
var depth = Convert.ToInt32(line);
num1 = num2;
num2 = num3;
num3 = depth;
int lastTotal = 0;
int numIncreased = -1;
int num1 = -1;
int num2 = -1;
int num3 = -1;
foreach (var line in lines)
if (num1 < 0 || num2 < 0 || num3 < 0)
{
var depth = Convert.ToInt32(line);
num1 = num2;
num2 = num3;
num3 = depth;
if (num1 < 0 || num2 < 0 || num3 < 0)
{
continue;
}
var total = num1 + num2 + num3;
if (total > lastTotal)
{
numIncreased++;
}
lastTotal = total;
continue;
}
Logger.Log($"part2: {numIncreased}");
var total = num1 + num2 + num3;
if (total > lastTotal)
{
numIncreased++;
}
lastTotal = total;
}
Logger.Log($"part2: {numIncreased}");
}
}

133
src/02.cs
View File

@ -1,90 +1,89 @@
namespace aoc2021
namespace aoc2021;
internal class Day02 : Day
{
internal class Day02
internal override void Go()
{
internal static void Go()
Logger.Log("Day 2");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/02.txt");
var instructions = new List<Instruction>();
foreach (var instruction in lines)
{
Logger.Log("Day 2");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/02.txt");
var instructions = new List<Instruction>();
foreach (var instruction in lines)
var fmt = instruction.Split(' ');
instructions.Add(new Instruction()
{
var fmt = instruction.Split(' ');
instructions.Add(new Instruction()
{
Direction = fmt[0],
Amount = Convert.ToInt64(fmt[1]),
});
}
Part1(instructions);
Part2(instructions);
Logger.Log("");
Direction = fmt[0],
Amount = Convert.ToInt64(fmt[1]),
});
}
struct Instruction
{
public string Direction;
public long Amount;
}
Part1(instructions);
Part2(instructions);
Logger.Log("");
}
struct Position
{
public long h;
public long d;
}
struct Instruction
{
public string Direction;
public long Amount;
}
private static void Part1(IEnumerable<Instruction> instructions)
struct Position
{
public long h;
public long d;
}
private static void Part1(IEnumerable<Instruction> instructions)
{
using var t = new Timer();
Position pos = new();
foreach (var instruction in instructions)
{
using var t = new Timer();
Position pos = new();
foreach (var instruction in instructions)
switch (instruction.Direction)
{
switch (instruction.Direction)
{
case "forward":
pos.h += instruction.Amount;
break;
case "forward":
pos.h += instruction.Amount;
break;
case "down":
pos.d += instruction.Amount;
break;
case "down":
pos.d += instruction.Amount;
break;
case "up":
pos.d -= instruction.Amount;
break;
}
case "up":
pos.d -= instruction.Amount;
break;
}
Logger.Log($"part1: h: {pos.h}, d: {pos.d}, result: {pos.h * pos.d}");
}
private static void Part2(IEnumerable<Instruction> instructions)
Logger.Log($"part1: h: {pos.h}, d: {pos.d}, result: {pos.h * pos.d}");
}
private static void Part2(IEnumerable<Instruction> instructions)
{
using var t = new Timer();
Position pos = new();
long aim = 0;
foreach (var instruction in instructions)
{
using var t = new Timer();
Position pos = new();
long aim = 0;
foreach (var instruction in instructions)
switch (instruction.Direction)
{
switch (instruction.Direction)
{
case "forward":
pos.h += instruction.Amount;
pos.d += aim * instruction.Amount;
break;
case "forward":
pos.h += instruction.Amount;
pos.d += aim * instruction.Amount;
break;
case "down":
aim += instruction.Amount;
break;
case "down":
aim += instruction.Amount;
break;
case "up":
aim -= instruction.Amount;
break;
}
case "up":
aim -= instruction.Amount;
break;
}
Logger.Log($"part2: h: {pos.h}, d: {pos.d}, result: {pos.h * pos.d}");
}
Logger.Log($"part2: h: {pos.h}, d: {pos.d}, result: {pos.h * pos.d}");
}
}

209
src/03.cs
View File

@ -1,132 +1,131 @@
namespace aoc2021
namespace aoc2021;
internal class Day03 : Day
{
internal class Day03
internal override void Go()
{
internal static void Go()
{
Logger.Log("Day 3");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/03.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
}
Logger.Log("Day 3");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/03.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
}
private static void Part1(IEnumerable<string> lines)
private static void Part1(IEnumerable<string> lines)
{
using var t = new Timer();
var len = lines.First().Length;
int gammaRate = 0;
int epsilonRate = 0;
for (int i = 0; i < len; i++)
{
using var t = new Timer();
var len = lines.First().Length;
int gammaRate = 0;
int epsilonRate = 0;
for (int i = 0; i < len; i++)
var numZero = 0;
var numOne = 0;
foreach (var line in lines)
{
var numZero = 0;
var numOne = 0;
foreach (var line in lines)
if (line[i] == '0')
{
if (line[i] == '0')
{
numZero++;
}
else if (line[i] == '1')
{
numOne++;
}
numZero++;
}
if (numOne > numZero)
else if (line[i] == '1')
{
gammaRate |= (1 << (len - i - 1));
}
else if (numZero > numOne)
{
epsilonRate |= (1 << (len - i - 1));
numOne++;
}
}
Logger.Log($"part1: gamma rate: {gammaRate}, epsilon rate: {epsilonRate}, mult: {gammaRate * epsilonRate}");
if (numOne > numZero)
{
gammaRate |= (1 << (len - i - 1));
}
else if (numZero > numOne)
{
epsilonRate |= (1 << (len - i - 1));
}
}
private static void Part2(IEnumerable<string> lines)
Logger.Log($"part1: gamma rate: {gammaRate}, epsilon rate: {epsilonRate}, mult: {gammaRate * epsilonRate}");
}
private static void Part2(IEnumerable<string> lines)
{
using var t = new Timer();
int o2 = 0;
int co2 = 0;
var filtered = lines.ToList();
for (int i = 0; i < lines.First().Length; i++)
{
using var t = new Timer();
int o2 = 0;
int co2 = 0;
var filtered = lines.ToList();
for (int i = 0; i < lines.First().Length; i++)
var numZero = 0;
var numOne = 0;
foreach (var line in filtered)
{
var numZero = 0;
var numOne = 0;
foreach (var line in filtered)
if (line[i] == '0')
{
if (line[i] == '0')
{
numZero++;
}
else if (line[i] == '1')
{
numOne++;
}
numZero++;
}
if (numOne > numZero)
else if (line[i] == '1')
{
filtered.RemoveAll(x => x[i] != '1');
}
else if (numZero > numOne)
{
filtered.RemoveAll(x => x[i] != '0');
}
else
{
filtered.RemoveAll(x => x[i] != '1');
}
if (filtered.Count == 1)
{
o2 = Convert.ToInt32(filtered[0], 2);
break;
numOne++;
}
}
filtered = lines.ToList();
for (int i = 0; i < lines.First().Length; i++)
if (numOne > numZero)
{
var numZero = 0;
var numOne = 0;
foreach (var line in filtered)
{
if (line[i] == '0')
{
numZero++;
}
else if (line[i] == '1')
{
numOne++;
}
}
if (numOne < numZero)
{
filtered.RemoveAll(x => x[i] != '1');
}
else if (numZero < numOne)
{
filtered.RemoveAll(x => x[i] != '0');
}
else
{
filtered.RemoveAll(x => x[i] != '0');
}
if (filtered.Count == 1)
{
co2 = Convert.ToInt32(filtered[0], 2);
break;
}
filtered.RemoveAll(x => x[i] != '1');
}
else if (numZero > numOne)
{
filtered.RemoveAll(x => x[i] != '0');
}
else
{
filtered.RemoveAll(x => x[i] != '1');
}
Logger.Log($"part2: o2*co2 = {o2} * {co2} = {o2 * co2}");
if (filtered.Count == 1)
{
o2 = Convert.ToInt32(filtered[0], 2);
break;
}
}
filtered = lines.ToList();
for (int i = 0; i < lines.First().Length; i++)
{
var numZero = 0;
var numOne = 0;
foreach (var line in filtered)
{
if (line[i] == '0')
{
numZero++;
}
else if (line[i] == '1')
{
numOne++;
}
}
if (numOne < numZero)
{
filtered.RemoveAll(x => x[i] != '1');
}
else if (numZero < numOne)
{
filtered.RemoveAll(x => x[i] != '0');
}
else
{
filtered.RemoveAll(x => x[i] != '0');
}
if (filtered.Count == 1)
{
co2 = Convert.ToInt32(filtered[0], 2);
break;
}
}
Logger.Log($"part2: o2*co2 = {o2} * {co2} = {o2 * co2}");
}
}

229
src/05.cs
View File

@ -1,130 +1,129 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace aoc2021
namespace aoc2021;
internal class Day05 : Day
{
internal class Day05
private static readonly Regex lineRegex = new(@"(?<x1>\d+),(?<y1>\d+) -> (?<x2>\d+),(?<y2>\d+)", RegexOptions.Compiled);
[DebuggerDisplay("{x},{y}")]
struct Point : IEquatable<Point>
{
private static readonly Regex lineRegex = new(@"(?<x1>\d+),(?<y1>\d+) -> (?<x2>\d+),(?<y2>\d+)", RegexOptions.Compiled);
public int X { get; init; }
public int Y { get; init; }
[DebuggerDisplay("{x},{y}")]
struct Point : IEquatable<Point>
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object? obj) => obj is Point point && Equals(point);
public override int GetHashCode() => HashCode.Combine(X, Y);
}
[DebuggerDisplay("{start} -> {end}")]
struct Line
{
public Point Start { get; init; }
public Point End { get; init; }
public int Length
{
public int X { get; init; }
public int Y { get; init; }
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object? obj) => obj is Point point && Equals(point);
public override int GetHashCode() => HashCode.Combine(X, Y);
}
[DebuggerDisplay("{start} -> {end}")]
struct Line
{
public Point Start { get; init; }
public Point End { get; init; }
public int Length
get
{
get
// this is bad and i feel bad
if (Start.X == End.X || Start.Y == End.Y)
{
// this is bad and i feel bad
if (Start.X == End.X || Start.Y == End.Y)
{
return Math.Abs((End.X - Start.X) + (End.Y - Start.Y));
}
return Math.Abs(Start.X - End.X);
}
}
}
internal static void Go()
{
Logger.Log("Day 5");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/05.txt");
List<Line> segments = new();
foreach (var line in lines)
{
var match = lineRegex.Match(line);
Line segment = new()
{
Start = new Point()
{
X = Convert.ToInt32(match.Groups["x1"].Value),
Y = Convert.ToInt32(match.Groups["y1"].Value),
},
End = new Point()
{
X = Convert.ToInt32(match.Groups["x2"].Value),
Y = Convert.ToInt32(match.Groups["y2"].Value)
},
};
segments.Add(segment);
}
Part1(segments);
Part2(segments);
Logger.Log("");
}
private static void Part1(IEnumerable<Line> lines)
{
using var t = new Timer();
int numPointsGreater = Solve(lines, (line) => !(line.Start.X == line.End.X || line.Start.Y == line.End.Y));
Logger.Log($"part1: {numPointsGreater}");
}
private static void Part2(IEnumerable<Line> lines)
{
using var t = new Timer();
int numPointsGreater = Solve(lines, (line) => false);
Logger.Log($"part2: {numPointsGreater}");
}
private static int Solve(IEnumerable<Line> lines, Func<Line, bool> filter)
{
Dictionary<Point, int> coveredPoints = new();
int numPointsGreater = 0;
foreach (var line in lines)
{
if (filter(line))
{
continue;
return Math.Abs((End.X - Start.X) + (End.Y - Start.Y));
}
for (int i = 0; i <= line.Length; i++)
{
int x = line.Start.X;
int y = line.Start.Y;
if (line.Start.X != line.End.X)
{
x += (line.Start.X > line.End.X ? -1 : 1) * i;
}
if (line.Start.Y != line.End.Y)
{
y += (line.Start.Y > line.End.Y ? -1 : 1) * i;
}
Point point = new() { X = x, Y = y };
if (!coveredPoints.TryGetValue(point, out int curr))
{
coveredPoints.Add(point, curr);
}
if (curr == 1)
{
numPointsGreater++;
}
coveredPoints[point] = curr + 1;
}
return Math.Abs(Start.X - End.X);
}
return numPointsGreater;
}
}
internal override void Go()
{
Logger.Log("Day 5");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/05.txt");
List<Line> segments = new();
foreach (var line in lines)
{
var match = lineRegex.Match(line);
Line segment = new()
{
Start = new Point()
{
X = Convert.ToInt32(match.Groups["x1"].Value),
Y = Convert.ToInt32(match.Groups["y1"].Value),
},
End = new Point()
{
X = Convert.ToInt32(match.Groups["x2"].Value),
Y = Convert.ToInt32(match.Groups["y2"].Value)
},
};
segments.Add(segment);
}
Part1(segments);
Part2(segments);
Logger.Log("");
}
private static void Part1(IEnumerable<Line> lines)
{
using var t = new Timer();
int numPointsGreater = Solve(lines, (line) => !(line.Start.X == line.End.X || line.Start.Y == line.End.Y));
Logger.Log($"part1: {numPointsGreater}");
}
private static void Part2(IEnumerable<Line> lines)
{
using var t = new Timer();
int numPointsGreater = Solve(lines, (line) => false);
Logger.Log($"part2: {numPointsGreater}");
}
private static int Solve(IEnumerable<Line> lines, Func<Line, bool> filter)
{
Dictionary<Point, int> coveredPoints = new();
int numPointsGreater = 0;
foreach (var line in lines)
{
if (filter(line))
{
continue;
}
for (int i = 0; i <= line.Length; i++)
{
int x = line.Start.X;
int y = line.Start.Y;
if (line.Start.X != line.End.X)
{
x += (line.Start.X > line.End.X ? -1 : 1) * i;
}
if (line.Start.Y != line.End.Y)
{
y += (line.Start.Y > line.End.Y ? -1 : 1) * i;
}
Point point = new() { X = x, Y = y };
if (!coveredPoints.TryGetValue(point, out int curr))
{
coveredPoints.Add(point, curr);
}
if (curr == 1)
{
numPointsGreater++;
}
coveredPoints[point] = curr + 1;
}
}
return numPointsGreater;
}
}

121
src/06.cs
View File

@ -1,81 +1,80 @@
using System.Diagnostics;
namespace aoc2021
namespace aoc2021;
internal class Day06 : Day
{
internal class Day06
[DebuggerDisplay("{State}")]
struct Fish
{
[DebuggerDisplay("{State}")]
struct Fish
public int State;
}
internal override void Go()
{
Logger.Log("Day 6");
Logger.Log("-----");
var input = File.ReadAllText("inputs/06.txt");
List<Fish> fish = new();
foreach (var state in input.Split(','))
{
public int State;
fish.Add(new Fish() { State = Convert.ToInt32(state) });
}
Part1(fish);
Part2(fish);
Logger.Log("");
}
internal static void Go()
private static void Part1(IEnumerable<Fish> fish)
{
using var t = new Timer();
var list = fish.ToList();
// brute force method (my initial solution)
for (int day = 0; day < 80; day++)
{
Logger.Log("Day 6");
Logger.Log("-----");
var input = File.ReadAllText("inputs/06.txt");
List<Fish> fish = new();
foreach (var state in input.Split(','))
for (int i = list.Count - 1; i >= 0; i--)
{
fish.Add(new Fish() { State = Convert.ToInt32(state) });
}
Part1(fish);
Part2(fish);
Logger.Log("");
}
private static void Part1(IEnumerable<Fish> fish)
{
using var t = new Timer();
var list = fish.ToList();
// brute force method (my initial solution)
for (int day = 0; day < 80; day++)
{
for (int i = list.Count - 1; i >= 0; i--)
Fish f = list[i];
if (f.State == 0)
{
Fish f = list[i];
if (f.State == 0)
{
list.Add(new Fish() { State = 8 });
f.State = 7;
}
f.State--;
list[i] = f;
list.Add(new Fish() { State = 8 });
f.State = 7;
}
f.State--;
list[i] = f;
}
}
#pragma warning disable CA1829 // Use Length/Count property instead of Count() when available - Count is of type int, list might be longer than that
Logger.Log($"part1: #fish={list.LongCount()}");
Logger.Log($"part1: #fish={list.LongCount()}");
#pragma warning restore CA1829 // Use Length/Count property instead of Count() when available
}
}
private static void Part2(IEnumerable<Fish> fish)
private static void Part2(IEnumerable<Fish> fish)
{
using var t = new Timer();
// fast method (when brute force threatened to blow RAM and take way too long)
Dictionary<int, long> fishAtState = new();
for (int i = 0; i <= 8; i++)
{
using var t = new Timer();
// fast method (when brute force threatened to blow RAM and take way too long)
Dictionary<int, long> fishAtState = new();
for (int i = 0; i <= 8; i++)
{
fishAtState[i] = fish.Count(x => x.State == i);
}
for (int day = 0; day < 256; day++)
{
var adders = fishAtState[0];
for (int i = 0; i < 8; i++)
{
fishAtState[i] = fishAtState[i + 1];
}
fishAtState[6] += adders;
fishAtState[8] = adders;
}
Logger.Log($"part2: #fish={fishAtState.Values.Sum()}");
fishAtState[i] = fish.Count(x => x.State == i);
}
for (int day = 0; day < 256; day++)
{
var adders = fishAtState[0];
for (int i = 0; i < 8; i++)
{
fishAtState[i] = fishAtState[i + 1];
}
fishAtState[6] += adders;
fishAtState[8] = adders;
}
Logger.Log($"part2: #fish={fishAtState.Values.Sum()}");
}
}

View File

@ -1,59 +1,58 @@
namespace aoc2021
namespace aoc2021;
internal class Day07 : Day
{
internal class Day07
internal override void Go()
{
internal static void Go()
{
Logger.Log("Day 7");
Logger.Log("-----");
var nums = File.ReadAllText("inputs/07.txt").Split(',').Select(int.Parse);
Part1(nums);
Part2(nums);
Logger.Log("");
}
Logger.Log("Day 7");
Logger.Log("-----");
var nums = File.ReadAllText("inputs/07.txt").Split(',').Select(int.Parse);
Part1(nums);
Part2(nums);
Logger.Log("");
}
private static (long, int) Solve(IEnumerable<int> nums, Func<long, long> formula)
private static (long, int) Solve(IEnumerable<int> nums, Func<long, long> formula)
{
var min = nums.Min();
var max = nums.Max();
long minDist = long.MaxValue;
int minNum = 0;
for (int i = min; i <= max; i++)
{
var min = nums.Min();
var max = nums.Max();
long minDist = long.MaxValue;
int minNum = 0;
for (int i = min; i <= max; i++)
long dist = 0;
foreach (var num in nums)
{
long dist = 0;
foreach (var num in nums)
{
dist += formula(Math.Abs(num - i));
}
if (dist < minDist)
{
minDist = dist;
minNum = i;
}
dist += formula(Math.Abs(num - i));
}
return (minDist, minNum);
if (dist < minDist)
{
minDist = dist;
minNum = i;
}
}
private static void Part1(IEnumerable<int> nums)
{
using var t = new Timer();
return (minDist, minNum);
}
var (minDist, minNum) = Solve(nums, (d) => d);
private static void Part1(IEnumerable<int> nums)
{
using var t = new Timer();
Logger.Log($"part1: position: {minNum}, fuel cost: {minDist}");
}
var (minDist, minNum) = Solve(nums, (d) => d);
private static void Part2(IEnumerable<int> nums)
{
using var t = new Timer();
Logger.Log($"part1: position: {minNum}, fuel cost: {minDist}");
}
// summation formula from https://en.wikipedia.org/wiki/Summation
// found by searching "factorial but with addition" because i'm smart like that.
var (minDist, minNum) = Solve(nums, (d) => ((d*d)+d)/2);
private static void Part2(IEnumerable<int> nums)
{
using var t = new Timer();
Logger.Log($"part2: position: {minNum}, fuel cost: {minDist}");
}
// summation formula from https://en.wikipedia.org/wiki/Summation
// found by searching "factorial but with addition" because i'm smart like that.
var (minDist, minNum) = Solve(nums, (d) => ((d * d) + d) / 2);
Logger.Log($"part2: position: {minNum}, fuel cost: {minDist}");
}
}

283
src/08.cs
View File

@ -1,174 +1,173 @@
namespace aoc2021
namespace aoc2021;
internal class Day08 : Day
{
internal class Day08
internal override void Go()
{
internal static void Go()
Logger.Log("Day 8");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/08.txt");
List<(List<string>, List<string>)> puzzle = new();
foreach (var line in lines)
{
Logger.Log("Day 8");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/08.txt");
List<(List<string>, List<string>)> puzzle = new();
foreach (var line in lines)
var portions = line.Split(" | ");
puzzle.Add((new List<string>(portions[0].Split(' ')), new List<string>(portions[1].Split(' '))));
}
Part1(puzzle);
Part2(puzzle);
Logger.Log("");
}
private static void Part1(List<(List<string>, List<string>)> lines)
{
using var t = new Timer();
int count = 0;
foreach (var line in lines)
{
foreach (var combo in line.Item2)
{
var portions = line.Split(" | ");
puzzle.Add((new List<string>(portions[0].Split(' ')), new List<string>(portions[1].Split(' '))));
switch (combo.Length)
{
case 2: // 1
case 4: // 4
case 3: // 7
case 7: // 8
count++;
break;
}
}
Part1(puzzle);
Part2(puzzle);
Logger.Log("");
}
private static void Part1(List<(List<string>, List<string>)> lines)
{
using var t = new Timer();
Logger.Log($"part1: {count}");
}
int count = 0;
foreach (var line in lines)
private static void Part2(List<(List<string>, List<string>)> lines)
{
using var t = new Timer();
long sum = 0;
foreach (var line in lines)
{
var segments = new char[7];
var one = line.Item1.First(x => x.Length == 2);
var four = line.Item1.First(x => x.Length == 4);
var seven = line.Item1.First(x => x.Length == 3);
var eight = line.Item1.First(x => x.Length == 7);
var len5 = line.Item1.Where(x => x.Length == 5); // 2, 3, 5
var len6 = line.Item1.Where(x => x.Length == 6); // 0, 6, 9
// top
segments[0] = seven.First(x => !one.Contains(x));
// bottom
foreach (var pattern in len6)
{
foreach (var combo in line.Item2)
var leftover = pattern.Where(x => !seven.Contains(x) && !four.Contains(x));
if (leftover.Count() == 1)
{
switch (combo.Length)
{
case 2: // 1
case 4: // 4
case 3: // 7
case 7: // 8
count++;
break;
}
segments[6] = leftover.First();
}
}
Logger.Log($"part1: {count}");
}
var three = len5.First(seg => seg.Contains(segments[0]) && seg.Contains(segments[6]) && seg.Contains(one[0]) && seg.Contains(one[1]));
// center
segments[3] = three.First(x => x != segments[0] && x != segments[6] && !one.Contains(x));
private static void Part2(List<(List<string>, List<string>)> lines)
{
using var t = new Timer();
// bottom left
segments[4] = eight.First(x => x != segments[0] && !four.Contains(x) && x != segments[6]);
long sum = 0;
foreach (var line in lines)
// top left
segments[1] = eight.First(x => !three.Contains(x) && x != segments[4]);
var two = len5.First(x => x.Where(y => y != segments[0] && y != segments[6]).Except(four).Count() == 1);
//var five = len5.First(x => x != two && x != three);
var nine = len6.First(x => !x.Except(four).Except(new List<char>() { segments[0], segments[6] }).Any());
var zero = len6.First(x => !x.Contains(segments[3]));
var six = len6.First(x => x != zero && x != nine);
// bottom right
segments[5] = six.Except(two).First(x => x != segments[1]);
// top right
segments[2] = one.First(x => x != segments[5]);
int num = 0;
for (int i = 0; i < line.Item2.Count; i++)
{
var segments = new char[7];
var one = line.Item1.First(x => x.Length == 2);
var four = line.Item1.First(x => x.Length == 4);
var seven = line.Item1.First(x => x.Length == 3);
var eight = line.Item1.First(x => x.Length == 7);
var len5 = line.Item1.Where(x => x.Length == 5); // 2, 3, 5
var len6 = line.Item1.Where(x => x.Length == 6); // 0, 6, 9
// top
segments[0] = seven.First(x => !one.Contains(x));
// bottom
foreach (var pattern in len6)
{
var leftover = pattern.Where(x => !seven.Contains(x) && !four.Contains(x));
if (leftover.Count() == 1)
{
segments[6] = leftover.First();
}
}
var three = len5.First(seg => seg.Contains(segments[0]) && seg.Contains(segments[6]) && seg.Contains(one[0]) && seg.Contains(one[1]));
// center
segments[3] = three.First(x => x != segments[0] && x != segments[6] && !one.Contains(x));
// bottom left
segments[4] = eight.First(x => x != segments[0] && !four.Contains(x) && x != segments[6]);
// top left
segments[1] = eight.First(x => !three.Contains(x) && x != segments[4]);
var two = len5.First(x => x.Where(y => y != segments[0] && y != segments[6]).Except(four).Count() == 1);
//var five = len5.First(x => x != two && x != three);
var nine = len6.First(x => !x.Except(four).Except(new List<char>() { segments[0], segments[6] }).Any());
var zero = len6.First(x => !x.Contains(segments[3]));
var six = len6.First(x => x != zero && x != nine);
// bottom right
segments[5] = six.Except(two).First(x => x != segments[1]);
// top right
segments[2] = one.First(x => x != segments[5]);
int num = 0;
for (int i = 0; i < line.Item2.Count; i++)
{
var numInt = FindNum(segments, line.Item2[i]);
num += numInt * (int)Math.Pow(10, (line.Item2.Count - i - 1));
}
sum += num;
var numInt = FindNum(segments, line.Item2[i]);
num += numInt * (int)Math.Pow(10, (line.Item2.Count - i - 1));
}
Logger.Log($"part2: {sum}");
sum += num;
}
private static int FindNum(char[] segments, string num)
Logger.Log($"part2: {sum}");
}
private static int FindNum(char[] segments, string num)
{
// i already solved for each number in part2, so it's kind of dumb to rebuild my own set of numbers here,
// but this is all left over from my various different attempts to solve this different ways.
// and it works, so whatever.
var zero = new List<char>() { segments[0], segments[1], segments[2], segments[4], segments[5], segments[6] };
var six = new List<char>() { segments[0], segments[1], segments[3], segments[4], segments[5], segments[6] };
var nine = new List<char>() { segments[0], segments[1], segments[2], segments[3], segments[5], segments[6] };
var two = new List<char>() { segments[0], segments[2], segments[3], segments[4], segments[6] };
var three = new List<char>() { segments[0], segments[2], segments[3], segments[5], segments[6] };
var five = new List<char>() { segments[0], segments[1], segments[3], segments[5], segments[6] };
switch (num.Length)
{
// i already solved for each number in part2, so it's kind of dumb to rebuild my own set of numbers here,
// but this is all left over from my various different attempts to solve this different ways.
// and it works, so whatever.
var zero = new List<char>() { segments[0], segments[1], segments[2], segments[4], segments[5], segments[6] };
var six = new List<char>() { segments[0], segments[1], segments[3], segments[4], segments[5], segments[6] };
var nine = new List<char>() { segments[0], segments[1], segments[2], segments[3], segments[5], segments[6] };
var two = new List<char>() { segments[0], segments[2], segments[3], segments[4], segments[6] };
var three = new List<char>() { segments[0], segments[2], segments[3], segments[5], segments[6] };
var five = new List<char>() { segments[0], segments[1], segments[3], segments[5], segments[6] };
case 2:
return 1;
switch (num.Length)
{
case 2:
return 1;
case 3:
return 7;
case 3:
return 7;
case 4:
return 4;
case 4:
return 4;
case 7:
return 8;
case 7:
return 8;
case 6:
if (num.All(x => zero.Contains(x)))
{
return 0;
}
else if (num.All(x => six.Contains(x)))
{
return 6;
}
else if (num.All(x => nine.Contains(x)))
{
return 9;
}
case 6:
if (num.All(x => zero.Contains(x)))
{
return 0;
}
else if (num.All(x => six.Contains(x)))
{
return 6;
}
else if (num.All(x => nine.Contains(x)))
{
return 9;
}
throw new Exception();
throw new Exception();
case 5:
if (num.All(x => two.Contains(x)))
{
return 2;
}
else if (num.All(x => three.Contains(x)))
{
return 3;
}
else if (num.All(x => five.Contains(x)))
{
return 5;
}
case 5:
if (num.All(x => two.Contains(x)))
{
return 2;
}
else if (num.All(x => three.Contains(x)))
{
return 3;
}
else if (num.All(x => five.Contains(x)))
{
return 5;
}
throw new Exception();
throw new Exception();
default:
throw new Exception();
}
throw new Exception();
default:
throw new Exception();
}
throw new Exception();
}
}

213
src/09.cs
View File

@ -1,128 +1,127 @@
namespace aoc2021
namespace aoc2021;
internal class Day09 : Day
{
internal class Day09
internal override void Go()
{
internal static void Go()
Logger.Log("Day 9");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/09.txt");
byte[,] grid = new byte[lines.Length, lines[0].Length];
for (int i = 0; i < lines.Length; i++)
{
Logger.Log("Day 9");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/09.txt");
byte[,] grid = new byte[lines.Length, lines[0].Length];
for (int i = 0; i < lines.Length; i++)
for (int j = 0; j < lines[i].Length; j++)
{
for (int j = 0; j < lines[i].Length; j++)
grid[i, j] = (byte)char.GetNumericValue(lines[i][j]);
}
}
Part1(grid);
Part2(grid);
Logger.Log("");
}
private static void Part1(byte[,] grid)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
var totalRisk = lowPoints.Sum(x => grid[x.Item1, x.Item2] + 1);
Logger.Log($"part1: {totalRisk}");
}
private static List<(int, int)> GetLowPoints(byte[,] grid)
{
List<(int, int)> lowPoints = new();
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
byte val = grid[i, j];
if (i > 0 && grid[i - 1, j] <= val)
{
grid[i, j] = (byte)char.GetNumericValue(lines[i][j]);
continue;
}
}
Part1(grid);
Part2(grid);
Logger.Log("");
}
private static void Part1(byte[,] grid)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
var totalRisk = lowPoints.Sum(x => grid[x.Item1, x.Item2] + 1);
Logger.Log($"part1: {totalRisk}");
}
private static List<(int, int)> GetLowPoints(byte[,] grid)
{
List<(int, int)> lowPoints = new();
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
if (i < grid.GetLength(0) - 1 && grid[i + 1, j] <= val)
{
byte val = grid[i, j];
if (i > 0 && grid[i - 1, j] <= val)
{
continue;
}
if (i < grid.GetLength(0) - 1 && grid[i + 1, j] <= val)
{
continue;
}
if (j > 0 && grid[i, j - 1] <= val)
{
continue;
}
if (j < grid.GetLength(1) - 1 && grid[i, j + 1] <= val)
{
continue;
}
lowPoints.Add((i, j));
continue;
}
if (j > 0 && grid[i, j - 1] <= val)
{
continue;
}
if (j < grid.GetLength(1) - 1 && grid[i, j + 1] <= val)
{
continue;
}
}
return lowPoints;
lowPoints.Add((i, j));
}
}
private static void Part2(byte[,] grid)
return lowPoints;
}
private static void Part2(byte[,] grid)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
List<int> basins = new();
foreach (var point in lowPoints)
{
using var t = new Timer();
var lowPoints = GetLowPoints(grid);
List<int> basins = new();
foreach (var point in lowPoints)
{
var basinPoints = GetBasinSize(grid, point.Item1, point.Item2);
basins.Add(basinPoints.Distinct().Count() + 1);
}
var top3Mult = basins.OrderByDescending(x => x).Take(3).Aggregate(1, (x,y) => x * y);
Logger.Log($"part2: {top3Mult}");
var basinPoints = GetBasinSize(grid, point.Item1, point.Item2);
basins.Add(basinPoints.Distinct().Count() + 1);
}
var top3Mult = basins.OrderByDescending(x => x).Take(3).Aggregate(1, (x, y) => x * y);
private static List<(int, int)> GetBasinSize(byte[,] grid, int i, int j)
Logger.Log($"part2: {top3Mult}");
}
private static List<(int, int)> GetBasinSize(byte[,] grid, int i, int j)
{
List<(int, int)> basinPoints = new();
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
List<(int, int)> basinPoints = new();
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
return new();
}
if (!basinPoints.Contains((i - 1, j)) && IsBasinPoint(grid, grid[i, j], i - 1, j))
{
basinPoints.Add((i - 1, j));
basinPoints.AddRange(GetBasinSize(grid, i - 1, j));
}
if (!basinPoints.Contains((i + 1, j)) && IsBasinPoint(grid, grid[i, j], i + 1, j))
{
basinPoints.Add((i + 1, j));
basinPoints.AddRange(GetBasinSize(grid, i + 1, j));
}
if (!basinPoints.Contains((i, j - 1)) && IsBasinPoint(grid, grid[i, j], i, j - 1))
{
basinPoints.Add((i, j - 1));
basinPoints.AddRange(GetBasinSize(grid, i, j - 1));
}
if (!basinPoints.Contains((i, j + 1)) && IsBasinPoint(grid, grid[i, j], i, j + 1))
{
basinPoints.Add((i, j + 1));
basinPoints.AddRange(GetBasinSize(grid, i, j + 1));
}
return basinPoints;
return new();
}
private static bool IsBasinPoint(byte[,] grid, byte val, int i, int j)
if (!basinPoints.Contains((i - 1, j)) && IsBasinPoint(grid, grid[i, j], i - 1, j))
{
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
return false;
}
if (grid[i, j] == 9 || val == 9)
{
return false;
}
return grid[i, j] > val;
basinPoints.Add((i - 1, j));
basinPoints.AddRange(GetBasinSize(grid, i - 1, j));
}
if (!basinPoints.Contains((i + 1, j)) && IsBasinPoint(grid, grid[i, j], i + 1, j))
{
basinPoints.Add((i + 1, j));
basinPoints.AddRange(GetBasinSize(grid, i + 1, j));
}
if (!basinPoints.Contains((i, j - 1)) && IsBasinPoint(grid, grid[i, j], i, j - 1))
{
basinPoints.Add((i, j - 1));
basinPoints.AddRange(GetBasinSize(grid, i, j - 1));
}
if (!basinPoints.Contains((i, j + 1)) && IsBasinPoint(grid, grid[i, j], i, j + 1))
{
basinPoints.Add((i, j + 1));
basinPoints.AddRange(GetBasinSize(grid, i, j + 1));
}
return basinPoints;
}
private static bool IsBasinPoint(byte[,] grid, byte val, int i, int j)
{
if (i >= grid.GetLength(0) || j >= grid.GetLength(1) || i < 0 || j < 0)
{
return false;
}
if (grid[i, j] == 9 || val == 9)
{
return false;
}
return grid[i, j] > val;
}
}

209
src/10.cs
View File

@ -1,62 +1,107 @@
namespace aoc2021
namespace aoc2021;
internal class Day10 : Day
{
internal class Day10
internal override void Go()
{
internal static void Go()
Logger.Log("Day 10");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/10.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
}
private static readonly List<char> Openers = new()
{
'(',
'[',
'{',
'<',
};
private static readonly List<char> Closers = new()
{
')',
']',
'}',
'>',
};
private static bool IsMatching(char open, char close) => Closers.IndexOf(close) == Openers.IndexOf(open);
private static void Part1(IEnumerable<string> lines)
{
List<int> charVals = new()
{
Logger.Log("Day 10");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/10.txt");
Part1(lines);
Part2(lines);
Logger.Log("");
3,
57,
1197,
25137,
};
using var t = new Timer();
long score = 0;
foreach (var line in lines)
{
var (corrupted, ch) = IsCorrupted(line);
if (corrupted)
{
score += charVals[Closers.IndexOf(ch)];
}
}
private static readonly List<char> Openers = new()
{
'(',
'[',
'{',
'<',
};
Logger.Log($"part1: {score}");
}
private static readonly List<char> Closers = new()
private static (bool, char) IsCorrupted(string line)
{
var s = new Stack<char>();
foreach (var ch in line)
{
')',
']',
'}',
'>',
};
private static bool IsMatching(char open, char close) => Closers.IndexOf(close) == Openers.IndexOf(open);
private static void Part1(IEnumerable<string> lines)
{
List<int> charVals = new()
if (Openers.Contains(ch))
{
3,
57,
1197,
25137,
};
using var t = new Timer();
long score = 0;
foreach (var line in lines)
s.Push(ch);
}
else if (Closers.Contains(ch))
{
var (corrupted, ch) = IsCorrupted(line);
if (corrupted)
var popped = s.Pop();
if (!IsMatching(popped, ch))
{
score += charVals[Closers.IndexOf(ch)];
return (true, ch);
}
}
Logger.Log($"part1: {score}");
else
{
throw new Exception();
}
}
private static (bool, char) IsCorrupted(string line)
return (false, '\0');
}
private static void Part2(IEnumerable<string> lines)
{
List<int> charVals = new()
{
1,
2,
3,
4,
};
using var t = new Timer();
List<long> scores = new();
foreach (var line in lines)
{
var (corrupted, _) = IsCorrupted(line);
if (corrupted)
{
continue;
}
var s = new Stack<char>();
foreach (var ch in line)
{
@ -66,11 +111,7 @@
}
else if (Closers.Contains(ch))
{
var popped = s.Pop();
if (!IsMatching(popped, ch))
{
return (true, ch);
}
s.Pop();
}
else
{
@ -78,65 +119,23 @@
}
}
return (false, '\0');
long score = 0;
while (s.Count > 0)
{
var ch = s.Pop();
score = (score * 5) + charVals[Openers.IndexOf(ch)];
}
scores.Add(score);
}
private static void Part2(IEnumerable<string> lines)
if (scores.Count % 2 == 0)
{
List<int> charVals = new()
{
1,
2,
3,
4,
};
using var t = new Timer();
List<long> scores = new();
foreach (var line in lines)
{
var (corrupted, _) = IsCorrupted(line);
if (corrupted)
{
continue;
}
var s = new Stack<char>();
foreach (var ch in line)
{
if (Openers.Contains(ch))
{
s.Push(ch);
}
else if (Closers.Contains(ch))
{
s.Pop();
}
else
{
throw new Exception();
}
}
long score = 0;
while (s.Count > 0)
{
var ch = s.Pop();
score = (score * 5) + charVals[Openers.IndexOf(ch)];
}
scores.Add(score);
}
if (scores.Count % 2 == 0)
{
throw new Exception();
}
var final = scores.OrderBy(x => x).Skip(scores.Count / 2).First();
Logger.Log($"part2: {final}");
throw new Exception();
}
var final = scores.OrderBy(x => x).Skip(scores.Count / 2).First();
Logger.Log($"part2: {final}");
}
}

View File

@ -1,8 +1,8 @@
namespace aoc2021;
internal class Day11
internal class Day11 : Day
{
internal static void Go()
internal override void Go()
{
Logger.Log("Day 11");
Logger.Log("-----");

View File

@ -1,8 +1,8 @@
namespace aoc2021;
internal class Day12
internal class Day12 : Day
{
internal static void Go()
internal override void Go()
{
Logger.Log("Day 12");
Logger.Log("-----");

6
src/Day.cs Normal file
View File

@ -0,0 +1,6 @@
namespace aoc2021;
internal abstract class Day
{
internal abstract void Go();
}

View File

@ -1,8 +1,8 @@
namespace aoc2021;
internal class DayTemplate
internal class DayTemplate : Day
{
internal static void Go()
internal override void Go()
{
Logger.Log("Day #");
Logger.Log("-----");

View File

@ -1,47 +1,36 @@
using aoc2021;
var arg = args.FirstOrDefault();
switch (arg)
if (arg == "all")
{
case "1":
aoc2021.Day01.Go();
break;
var types = System.Reflection.Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(Day)) && !t.IsAbstract && t.Name != "DayTemplate")
.OrderBy(t => t.Name);
case "2":
aoc2021.Day02.Go();
break;
case "3":
aoc2021.Day03.Go();
break;
case "5":
aoc2021.Day05.Go();
break;
case "6":
aoc2021.Day06.Go();
break;
case "7":
aoc2021.Day07.Go();
break;
case "8":
aoc2021.Day08.Go();
break;
case "9":
aoc2021.Day09.Go();
break;
case "10":
aoc2021.Day10.Go();
break;
case "11":
aoc2021.Day11.Go();
break;
default:
aoc2021.Day12.Go();
break;
foreach (var type in types)
{
var day = (Day)Activator.CreateInstance(type)!;
day.Go();
}
}
else
{
Day day = arg switch
{
"1" => new Day01(),
"2" => new Day02(),
"3" => new Day03(),
//"4" => new Day04(),
"5" => new Day05(),
"6" => new Day06(),
"7" => new Day07(),
"8" => new Day08(),
"9" => new Day09(),
"10" => new Day10(),
"11" => new Day11(),
_ => new Day12(),
};
day.Go();
}