Initial Commit
This commit is contained in:
319
2022/Day11CSharp/Program.cs
Normal file
319
2022/Day11CSharp/Program.cs
Normal file
@@ -0,0 +1,319 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
Part01();
|
||||
Console.WriteLine();
|
||||
Part02();
|
||||
|
||||
void Part01()
|
||||
{
|
||||
Console.WriteLine("!! === Part 1 === !!");
|
||||
var exampleMonkeys = Monkey.LoadMonkeys("example-input.txt");
|
||||
var puzzleMonkeys = Monkey.LoadMonkeys("puzzle-input.txt");
|
||||
|
||||
Simulation exampleSim = new Simulation(exampleMonkeys);
|
||||
Simulation puzzleSim = new Simulation(puzzleMonkeys);
|
||||
|
||||
Console.WriteLine(" === Example ===");
|
||||
exampleSim.ProcessRound(20);
|
||||
exampleSim.PrintMonkeys();
|
||||
Console.WriteLine("Monkey business: " + exampleSim.MonkeyBusiness);
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
Console.WriteLine(" === Puzzle ===");
|
||||
puzzleSim.ProcessRound(20);
|
||||
puzzleSim.PrintMonkeys();
|
||||
Console.WriteLine("Monkey business: " + puzzleSim.MonkeyBusiness);
|
||||
}
|
||||
|
||||
void Part02()
|
||||
{
|
||||
Console.WriteLine("!! === Part 2 === !!");
|
||||
var exampleMonkeys = Monkey.LoadMonkeys("example-input.txt");
|
||||
var puzzleMonkeys = Monkey.LoadMonkeys("puzzle-input.txt");
|
||||
|
||||
Simulation exampleSim = new Simulation(exampleMonkeys);
|
||||
Simulation puzzleSim = new Simulation(puzzleMonkeys);
|
||||
|
||||
Console.WriteLine(" === Example ===");
|
||||
exampleSim.ProcessRound(10000, false, true);
|
||||
exampleSim.PrintMonkeys();
|
||||
Console.WriteLine("Monkey business: " + exampleSim.MonkeyBusiness);
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
Console.WriteLine(" === Puzzle ===");
|
||||
puzzleSim.ProcessRound(10000, false, true);
|
||||
puzzleSim.PrintMonkeys();
|
||||
Console.WriteLine("Monkey business: " + puzzleSim.MonkeyBusiness);
|
||||
}
|
||||
|
||||
class Simulation
|
||||
{
|
||||
private List<Monkey> Monkeys { get; set; }
|
||||
private bool AutoDropWorry { get; set; }
|
||||
public Simulation(List<Monkey> monkeys)
|
||||
{
|
||||
Monkeys = monkeys;
|
||||
}
|
||||
|
||||
public BigInteger MonkeyBusiness
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = new List<Monkey>(Monkeys);
|
||||
list.Sort();
|
||||
BigInteger left = list[list.Count - 1].InspectedCount;
|
||||
BigInteger right = list[list.Count - 2].InspectedCount;
|
||||
|
||||
return left * right;
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessRound(int rounds = 1, bool part01 = true, bool printProgress = false)
|
||||
{
|
||||
int mod = Monkeys[0].Test.divisibility;
|
||||
for (int i = 1 ; i < Monkeys.Count; i++)
|
||||
{
|
||||
mod *= Monkeys[i].Test.divisibility;
|
||||
}
|
||||
|
||||
if (printProgress)
|
||||
{
|
||||
Console.Write("Processing: ");
|
||||
Console.Out.Flush();
|
||||
|
||||
}
|
||||
|
||||
for (int round = 0; round < rounds; round++)
|
||||
{
|
||||
if (printProgress && round % 100 == 0)
|
||||
{
|
||||
Console.Write(String.Format("{0}%..", (float)round / rounds * 100));
|
||||
Console.Out.Flush();
|
||||
}
|
||||
foreach (Monkey m in Monkeys)
|
||||
{
|
||||
var oldItemList = m.Items;
|
||||
m.Items = new List<BigInteger>();
|
||||
m.InspectedCount += oldItemList.Count;
|
||||
|
||||
foreach (var item in oldItemList)
|
||||
{
|
||||
var i = item;
|
||||
|
||||
// Worry operation
|
||||
i = m.Operation.GetNewValue(i);
|
||||
|
||||
// Bored
|
||||
if (part01) i /= 3;
|
||||
else i = i % mod;
|
||||
|
||||
// Test
|
||||
int dest = m.Test.DoTest(i);
|
||||
Monkeys[dest].Items.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printProgress) Console.WriteLine("..Done!");
|
||||
}
|
||||
|
||||
public void PrintMonkeys()
|
||||
{
|
||||
for (int i = 0; i < Monkeys.Count; i++)
|
||||
{
|
||||
Console.Write(String.Format("Monkey {0} Inspected({1}), Items: ", i, Monkeys[i].InspectedCount));
|
||||
|
||||
bool first = true;
|
||||
foreach (var item in Monkeys[i].Items)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
Console.Write(", ");
|
||||
}
|
||||
first = false;
|
||||
Console.Write(item);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Operation
|
||||
{
|
||||
public Operation(char op, string value)
|
||||
{
|
||||
this.op = op;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public BigInteger GetNewValue(BigInteger worryLevel)
|
||||
{
|
||||
BigInteger realVal;
|
||||
|
||||
if (!BigInteger.TryParse(value, out realVal))
|
||||
{
|
||||
realVal = worryLevel;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case '+':
|
||||
return worryLevel + realVal;
|
||||
case '-':
|
||||
return worryLevel - realVal;
|
||||
case '*':
|
||||
return worryLevel * realVal;
|
||||
case '/':
|
||||
return worryLevel / realVal;
|
||||
default:
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Operation Parse(string line)
|
||||
{
|
||||
if (!line.Trim().StartsWith("Operation:"))
|
||||
throw new InvalidDataException();
|
||||
|
||||
var split = line.Split('=')[1].Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
char op = split[1][0];
|
||||
string value = split[2];
|
||||
|
||||
return new Operation(op, value);
|
||||
}
|
||||
|
||||
private char op;
|
||||
private string value;
|
||||
}
|
||||
|
||||
class Test
|
||||
{
|
||||
public Test(string[] line)
|
||||
{
|
||||
if (line.Length != 3)
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
|
||||
string[] split;
|
||||
|
||||
// Get the divis by val
|
||||
split = line[0].Split(' ');
|
||||
divisibility = Int32.Parse(split[split.Length - 1]);
|
||||
|
||||
// True
|
||||
split = line[1].Split(' ');
|
||||
trueMonkeyTarget = Int32.Parse(split[split.Length - 1]);
|
||||
|
||||
// False
|
||||
split = line[2].Split(' ');
|
||||
falseMonkeyTarget = Int32.Parse(split[split.Length - 1]);
|
||||
}
|
||||
|
||||
public int divisibility { get; set; }
|
||||
private int trueMonkeyTarget { get; set; }
|
||||
private int falseMonkeyTarget { get; set; }
|
||||
|
||||
public int DoTest(BigInteger worryLevel)
|
||||
{
|
||||
if (worryLevel % divisibility == 0)
|
||||
{
|
||||
return trueMonkeyTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
return falseMonkeyTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Monkey : IComparable
|
||||
{
|
||||
public List<BigInteger> Items { get; set; } = new List<BigInteger>();
|
||||
|
||||
public Operation Operation { get; set; }
|
||||
|
||||
public Test Test { get; set; }
|
||||
|
||||
public int InspectedCount { get; set; } = 0;
|
||||
|
||||
public Monkey(string[] lines)
|
||||
{
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
string line = lines[i];
|
||||
|
||||
if (line.Trim().StartsWith("Operation:"))
|
||||
{
|
||||
Operation = Operation.Parse(line);
|
||||
}
|
||||
else if (line.Trim().StartsWith("Starting items:"))
|
||||
{
|
||||
var entries = line.Split(':')[1].Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
int val = int.Parse(entry);
|
||||
Items.Add(val);
|
||||
}
|
||||
}
|
||||
else if (line.Trim().StartsWith("Test:"))
|
||||
{
|
||||
string[] testLines = new string[3];
|
||||
testLines[0] = line;
|
||||
testLines[1] = lines[i+1];
|
||||
testLines[2] = lines[i+2];
|
||||
|
||||
Test = new Test(testLines);
|
||||
}
|
||||
}
|
||||
|
||||
if (Operation == null || Test == null) throw new InvalidDataException();
|
||||
}
|
||||
|
||||
public static List<Monkey> LoadMonkeys(string filename)
|
||||
{
|
||||
List<Monkey> monkeys = new List<Monkey>();
|
||||
|
||||
using (StreamReader reader = System.IO.File.OpenText(filename))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
string? line = reader.ReadLine();
|
||||
if (line == null) throw new InvalidDataException();
|
||||
|
||||
if (line.StartsWith("Monkey"))
|
||||
{
|
||||
string[] lines = new string[5];
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
string? newLine = reader.ReadLine();
|
||||
if (newLine == null) throw new InvalidDataException();
|
||||
lines[i] = newLine;
|
||||
}
|
||||
monkeys.Add(new Monkey(lines));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return monkeys;
|
||||
}
|
||||
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
if (obj == null) throw new InvalidDataException();
|
||||
|
||||
Monkey Temp = (Monkey)obj;
|
||||
if (this.InspectedCount < Temp.InspectedCount)
|
||||
return -1;
|
||||
if (this.InspectedCount > Temp.InspectedCount)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user