Initial Commit
This commit is contained in:
231
2022/Day10CSharp/Program.cs
Normal file
231
2022/Day10CSharp/Program.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user