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

231 lines
5.2 KiB
C#

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
var exampleInstructions01 = Instruction.LoadInstructions("example-input1.txt");
var exampleInstructions02 = Instruction.LoadInstructions("example-input2.txt");
var puzzleInstructions = Instruction.LoadInstructions("puzzle-input.txt");
// Part 01
outputSignalStrength(exampleInstructions02, 20, 40);
outputSignalStrength(puzzleInstructions, 20, 40);
// Part 02
Console.Write(" === Writing Example Output === ");
renderOnCrt(exampleInstructions02);
Console.WriteLine();
Console.WriteLine();
Console.Write(" === Writing Puzzle Output === ");
renderOnCrt(puzzleInstructions);
Console.WriteLine();
bool ShouldDrawSprite(int position, int cycle)
{
return (position + 0) % 40 == cycle % 40
|| (position - 1) % 40 == cycle % 40
|| (position + 1) % 40 == cycle % 40;
}
void Draw(int spritePosition, CPU cpu)
{
if (cpu.Cycle % 40 == 0) Console.WriteLine();
if (ShouldDrawSprite(spritePosition, cpu.Cycle))
{
Console.Write('#');
}
else
{
Console.Write('.');
}
}
void renderOnCrt(List<Instruction> instructions)
{
int spritePosition;
CPU cpu = new CPU();
foreach (var i in instructions)
{
spritePosition = cpu.GetRegisterValue('X');
if (i.CycleCount() == 1)
{
Draw(spritePosition, cpu);
cpu.Execute(i);
}
else if (i.CycleCount() == 2)
{
Draw(spritePosition, cpu);
cpu.Cycle++;
Draw(spritePosition, cpu);
cpu.Execute(i);
cpu.Cycle--;
}
else throw new InvalidDataException();
}
}
void outputSignalStrength(List<Instruction> list, int init, int step)
{
CPU cpu = new CPU();
int nextSignal = init;
List<int> strengthList = new List<int>();
Console.WriteLine(" === Listing signals ===");
foreach (var l in list)
{
int oldValue = cpu.GetRegisterValue('X');
cpu.Execute(l);
if (cpu.Cycle >= nextSignal)
{
int strength = nextSignal * oldValue;
Console.WriteLine(String.Format("Cycle({0}): SignalStrength({1})", nextSignal, strength));
strengthList.Add(strength);
nextSignal += step;
}
}
int strengthSum = 0;
foreach (var s in strengthList)
{
strengthSum += s;
}
Console.WriteLine("Strength Sum: " + strengthSum);
Console.WriteLine();
}
class CPU
{
public int Cycle
{
get; set;
}
private int registerX;
public CPU()
{
Cycle = 0;
registerX = 1;
}
public int GetRegisterValue(char registerName)
{
switch (registerName)
{
case 'X':
return registerX;
default:
throw new ArgumentException();
}
}
public void SetRegisterValue(char registerName, int value)
{
switch (registerName)
{
case 'X':
registerX = value;
break;
default: throw new ArgumentException();
}
}
public void Execute(Instruction i)
{
i.Execute(this);
}
}
abstract class Instruction
{
public virtual void Execute(CPU cpu, params int[] list)
{
cpu.Cycle += CycleCount();
}
public abstract int CycleCount();
static Instruction ParseInstruction(string line)
{
if (line.StartsWith("noop"))
{
return new NoopInstruction();
}
if (line.StartsWith("addx"))
{
var split = line.Split(' ');
return new AddInstruction('X', Int32.Parse(split[1]));
}
throw new InvalidDataException();
}
public static List<Instruction> LoadInstructions(string filename)
{
List<Instruction> list = new List<Instruction>();
using (StreamReader reader = System.IO.File.OpenText(filename))
{
while (!reader.EndOfStream)
{
string? line = reader.ReadLine();
if (line == null) throw new InvalidDataException();
list.Add(ParseInstruction(line));
}
}
return list;
}
}
class NoopInstruction : Instruction
{
public override void Execute(CPU cpu, params int[] list)
{
base.Execute(cpu, list);
}
public override int CycleCount()
{
return 1;
}
}
class AddInstruction : Instruction
{
public AddInstruction(char register, int value)
{
Value = value;
Register = register;
}
public int Value
{
get; set;
}
public char Register
{
get; set;
}
public override void Execute(CPU cpu, params int[] list)
{
base.Execute(cpu, list);
cpu.SetRegisterValue(Register, cpu.GetRegisterValue(Register) + Value);
}
public override int CycleCount()
{
return 2;
}
}