Initial Commit
This commit is contained in:
334
2022/Day13CSharp/Program.cs
Normal file
334
2022/Day13CSharp/Program.cs
Normal file
@@ -0,0 +1,334 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Markup;
|
||||
|
||||
|
||||
Part01();
|
||||
Console.WriteLine();
|
||||
Part02();
|
||||
|
||||
void Part01()
|
||||
{
|
||||
Console.WriteLine("!! === Part 1 === !!");
|
||||
Console.WriteLine(" === Example Data ===");
|
||||
var examplePackets = ReadPacketPairs("example-input.txt");
|
||||
//PrintPackets(examplePackets);
|
||||
Console.WriteLine("Sum of combined pair indices: " + GetSumOfOrderedPairs(examplePackets));
|
||||
|
||||
Console.WriteLine(" === Puzzle Data ===");
|
||||
var puzzlePackets = ReadPacketPairs("puzzle-input.txt");
|
||||
//PrintPackets(puzzlePackets);
|
||||
Console.WriteLine("Sum of combined pair indices: " + GetSumOfOrderedPairs(puzzlePackets));
|
||||
}
|
||||
|
||||
void Part02()
|
||||
{
|
||||
Console.WriteLine("!! === Part 2 === !!");
|
||||
Console.WriteLine(" === Example Data ===");
|
||||
var examplePackets = ReadPackets("example-input.txt");
|
||||
InsertDividers(examplePackets);
|
||||
examplePackets.Sort();
|
||||
PrintPart02Sln(examplePackets);
|
||||
|
||||
Console.WriteLine(" === Puzzle Data ===");
|
||||
var puzzlePackets = ReadPackets("puzzle-input.txt");
|
||||
InsertDividers(puzzlePackets);
|
||||
puzzlePackets.Sort();
|
||||
PrintPart02Sln(puzzlePackets);
|
||||
}
|
||||
|
||||
void PrintPart02Sln(List<IComparable> packets)
|
||||
{
|
||||
var dividers = GetDividers();
|
||||
int first = -1;
|
||||
int second = -1;
|
||||
int index = 1;
|
||||
|
||||
foreach (var packet in packets)
|
||||
{
|
||||
if (packet.CompareTo(dividers.Data.Item1) == 0) first = index;
|
||||
if (packet.CompareTo(dividers.Data.Item2) == 0) second = index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
Console.WriteLine("Dividers at {0} and {1}. Key: {2}", first, second, first * second);
|
||||
}
|
||||
|
||||
int GetSumOfOrderedPairs(List<PacketPair> packetPairs)
|
||||
{
|
||||
int sum = 0, index = 1;
|
||||
foreach (var packet in packetPairs)
|
||||
{
|
||||
if (packet.IsCorrectlyOrdered()) sum += index;
|
||||
index++;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void InsertDividers(List<IComparable> packets)
|
||||
{
|
||||
PacketPair pair = GetDividers();
|
||||
packets.Add(pair.Data.Item1);
|
||||
packets.Add(pair.Data.Item2);
|
||||
}
|
||||
|
||||
PacketPair GetDividers()
|
||||
{
|
||||
return new PacketPair("[[2]]", "[[6]]");
|
||||
}
|
||||
|
||||
void PrintPacketPairs(List<PacketPair> packets)
|
||||
{
|
||||
Console.WriteLine("- Printing packets -");
|
||||
foreach (var packet in packets) Console.WriteLine(String.Format("{0} {1} correctly ordered.", packet.ToString(), packet.IsCorrectlyOrdered() ? "is" : "is NOT"));
|
||||
//foreach (var packet in packets)
|
||||
//{
|
||||
// Console.WriteLine(packet.Data.Item1.ToString());
|
||||
// Console.WriteLine(packet.Data.Item2.ToString());
|
||||
// Console.WriteLine();
|
||||
//}
|
||||
Console.WriteLine("- Done -");
|
||||
}
|
||||
|
||||
List<IComparable> ReadPackets(string filename)
|
||||
{
|
||||
List<IComparable> packets = new List<IComparable>();
|
||||
|
||||
foreach (var pair in ReadPacketPairs(filename))
|
||||
{
|
||||
if (pair == null) throw new InvalidDataException();
|
||||
|
||||
packets.Add(pair.Data.Item1);
|
||||
packets.Add(pair.Data.Item2);
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
|
||||
List<PacketPair> ReadPacketPairs(string filename)
|
||||
{
|
||||
List<PacketPair> packets = new List<PacketPair>();
|
||||
|
||||
using (StreamReader reader = System.IO.File.OpenText(filename))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
// Read the next two lines
|
||||
string? left = reader.ReadLine();
|
||||
string? right = reader.ReadLine();
|
||||
|
||||
if (left == null || right == null) throw new InvalidDataException();
|
||||
|
||||
packets.Add(new PacketPair(left, right));
|
||||
|
||||
// Read the empty line
|
||||
reader.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
|
||||
class PacketPair
|
||||
{
|
||||
public PacketPair(string dataLeft, string dataRight)
|
||||
{
|
||||
ListData left = Parse(dataLeft);
|
||||
ListData right = Parse(dataRight);
|
||||
|
||||
Data = new Tuple<IComparable, IComparable>(left, right);
|
||||
}
|
||||
|
||||
private int Parse(ListData list, string data, int currentIndex)
|
||||
{
|
||||
if (data[currentIndex] != '[') throw new InvalidDataException();
|
||||
|
||||
for (int i = currentIndex+1; i < data.Length; i++)
|
||||
{
|
||||
if (data[i] == ',') continue;
|
||||
|
||||
if (data[i] == '[')
|
||||
{
|
||||
ListData newList = new ListData();
|
||||
// Found a list
|
||||
i = Parse(newList, data, i);
|
||||
|
||||
list.Values.Add(newList);
|
||||
}
|
||||
else if (Char.IsDigit(data[i]))
|
||||
{
|
||||
int strlen = 0;
|
||||
for (int j = i; Char.IsDigit(data[j]); j++,strlen++);
|
||||
|
||||
list.Values.Add(new IntegerData(Int32.Parse(data.Substring(i, strlen))));
|
||||
|
||||
while (data[i] != ',' && data[i] != ']') i++;
|
||||
if (data[i] == ',')
|
||||
{
|
||||
// Move to the next piece of data
|
||||
continue;
|
||||
}
|
||||
else if (data[i] == ']')
|
||||
{
|
||||
// We're done with the values of this object, we can exit
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else if (data[i] == ']')
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
|
||||
private ListData Parse(string data)
|
||||
{
|
||||
ListData list = new ListData();
|
||||
|
||||
Parse(list, data, 0);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Tuple<IComparable, IComparable> Data {get; set;}
|
||||
|
||||
public bool IsCorrectlyOrdered()
|
||||
{
|
||||
return Data.Item1.CompareTo(Data.Item2) <= 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Data.Item1.ToString() + " vs " + Data.Item2.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerData : IComparable
|
||||
{
|
||||
public IntegerData(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public int Value { get; set;}
|
||||
|
||||
public int CompareTo(object? right)
|
||||
{
|
||||
var integerData = right as IntegerData;
|
||||
var listData = right as ListData;
|
||||
|
||||
if (integerData != null)
|
||||
{
|
||||
return Value.CompareTo(integerData.Value);
|
||||
}
|
||||
else if (listData != null)
|
||||
{
|
||||
ListData leftList = new ListData();
|
||||
leftList.Values.Add(this);
|
||||
return leftList.CompareTo(listData);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
class ListData : IComparable
|
||||
{
|
||||
public List<IComparable> Values { get; set;} = new List<IComparable>();
|
||||
|
||||
public int CompareTo(object? obj)
|
||||
{
|
||||
var integerData = obj as IntegerData;
|
||||
var listData = obj as ListData;
|
||||
|
||||
if (integerData != null)
|
||||
{
|
||||
ListData rightList = new ListData();
|
||||
rightList.Values.Add(integerData);
|
||||
return CompareLists(this, rightList);
|
||||
}
|
||||
else if (listData != null)
|
||||
{
|
||||
return CompareLists(this, listData);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
int CompareLists(ListData left, ListData right)
|
||||
{
|
||||
if (left.Values.Count == 0 && right.Values.Count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (left.Values.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (left.Values.Count > 0 && right.Values.Count == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
if (i < left.Values.Count && i < right.Values.Count)
|
||||
{
|
||||
var result = left.Values[i].CompareTo(right.Values[i]);
|
||||
|
||||
if (result != 0) return result;
|
||||
}
|
||||
else if (i == left.Values.Count && i == right.Values.Count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (i >= left.Values.Count)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (i >= right.Values.Count)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string str = "";
|
||||
|
||||
str += '[';
|
||||
|
||||
for (int i = 0; i < Values.Count; i++)
|
||||
{
|
||||
if (i > 0) str += ',';
|
||||
|
||||
str += Values[i].ToString();
|
||||
}
|
||||
str += "]";
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user