Files
AdventOfCode/2022/Day05CSharp/Program.cs
2025-11-30 20:28:10 -05:00

233 lines
7.1 KiB
C#

using System.Net;
using System.Runtime.CompilerServices;
using static LoadedData;
const string puzzleFileName = @"puzzle-input.txt";
const string exampleFileName = @"example-input.txt";
Part01();
Part02();
static void Part01()
{
Console.WriteLine("\n****** UNORDERED ******\n");
var exampleData = new LoadedData(exampleFileName);
var puzzleData = new LoadedData(puzzleFileName);
Console.WriteLine("exmample top crates");
exampleData.PrintTopCrates();
Console.WriteLine("performing ops");
exampleData.PerformOperationsUnordered(exampleData.Operations.Count);
Console.WriteLine("exmample top crates");
exampleData.PrintTopCrates();
Console.WriteLine("\n****** PUZZLE ******\n");
Console.WriteLine("puzzle top crates");
puzzleData.PrintTopCrates();
Console.WriteLine("performing ops");
puzzleData.PerformOperationsUnordered(puzzleData.Operations.Count);
Console.WriteLine("puzzle top crates");
puzzleData.PrintTopCrates();
}
static void Part02()
{
Console.WriteLine("\n****** ORDERED ******\n");
var exampleData = new LoadedData(exampleFileName);
var puzzleData = new LoadedData(puzzleFileName);
Console.WriteLine("exmample top crates");
exampleData.PrintTopCrates();
Console.WriteLine("performing ops");
exampleData.PerformOperationsOrdered(exampleData.Operations.Count);
Console.WriteLine("exmample top crates");
exampleData.PrintTopCrates();
Console.WriteLine("\n****** PUZZLE ******\n");
Console.WriteLine("puzzle top crates");
puzzleData.PrintTopCrates();
Console.WriteLine("performing ops");
puzzleData.PerformOperationsOrdered(puzzleData.Operations.Count);
Console.WriteLine("puzzle top crates");
puzzleData.PrintTopCrates();
}
class LoadedData
{
public class Crate
{
public Crate(char c)
{
Name = c;
}
public char Name { get; set; }
}
public List<Crate>[] Crates { get; set; }
public int StackCount { get { return Crates.Length; } }
public class Operation
{
public Operation(int crateCount, int sourceStack, int destinationStack)
{
CrateCount = crateCount;
SourceStack = sourceStack;
DestinationStack = destinationStack;
}
public int CrateCount { get; set; }
public int SourceStack { get; set; }
public int DestinationStack { get; set; }
}
public List<Operation> Operations { get; set; } = new List<Operation>();
private int operationIndex = 0;
public void PrintTopCrates()
{
string printout = "";
foreach (var stack in Crates)
{
printout += String.Format("{0}", stack[stack.Count - 1].Name);
}
Console.WriteLine(printout);
}
public void PerformOperationsUnordered(int count)
{
if (operationIndex + count > Operations.Count)
{
throw new ArgumentOutOfRangeException("Too many operations requested");
}
if (count > 0)
{
for (; operationIndex < Operations.Count; operationIndex++)
{
Operation op = Operations[operationIndex];
for (int i = 0; i < op.CrateCount; i++)
{
int sourceIndex = op.SourceStack - 1;
int destinationIndex = op.DestinationStack - 1;
var crate = Crates[sourceIndex][Crates[sourceIndex].Count - 1];
Crates[sourceIndex].RemoveAt(Crates[sourceIndex].Count - 1);
Crates[destinationIndex].Add(crate);
}
}
}
}
public void PerformOperationsOrdered(int count)
{
if (operationIndex + count > Operations.Count)
{
throw new ArgumentOutOfRangeException("Too many operations requested");
}
if (count > 0)
{
for (; operationIndex < Operations.Count; operationIndex++)
{
Operation op = Operations[operationIndex];
int sourceIndex = op.SourceStack - 1;
int destinationIndex = op.DestinationStack - 1;
int destStackIndex = Crates[destinationIndex].Count;
for (int i = 0; i < op.CrateCount; i++)
{
var crate = Crates[sourceIndex][Crates[sourceIndex].Count - 1];
Crates[sourceIndex].RemoveAt(Crates[sourceIndex].Count - 1);
Crates[destinationIndex].Insert(destStackIndex, crate);
}
}
}
}
public LoadedData(string fileName)
{
using (StreamReader reader = File.OpenText(fileName))
{
while (!reader.EndOfStream)
{
string? line = reader.ReadLine();
if (line == null || (line.Length+1) % 4 != 0)
{
throw new InvalidDataException();
}
// It's the first line, create the list
if (Crates == null)
{
int length = (line.Length+1) / 4;
Crates = new List<Crate>[length];
for (int i = 0; i < Crates.Length; i++)
{
Crates[i] = new List<Crate>();
}
}
// Validate line length
if ((StackCount*4)-1 > line.Length)
{
throw new ArgumentOutOfRangeException();
}
// Check for the crate number line
if (Char.IsAsciiDigit(line[1]))
{
break;
}
// Read in each crate
for (int i = 0; i < StackCount; i++)
{
// Read in the entry
char c = line[(i * 4) + 1];
if (c != ' ')
{
if (!Char.IsLetter(c))
{
throw new InvalidDataException();
}
Crates[i].Insert(0, new Crate(c));
}
}
}
// Read in the empty line
reader.ReadLine();
while (!reader.EndOfStream)
{
string? line = reader.ReadLine();
if (line == null)
{
throw new InvalidDataException();
}
var split = line.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (split.Length < 5)
{
throw new InvalidDataException();
}
Operations.Add(new Operation(Int32.Parse(split[1]), Int32.Parse(split[3]), Int32.Parse(split[5])));
}
}
}
}