aoc2016/csharp/bscott09.cs

142 lines
5.7 KiB
C#

/*
* Advent of Code 2016
* Day 9 (part 1 and 2)
*/
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace adventofcode
{
class bscott09
{
public static long CalcDecompressedLength(string input, bool recursive = false, int level = 0)
{
long decompressedLength = 0;
MatchCollection matchCollection = Regex.Matches(input, @"\((\d+)x(\d+)\)");
int lastMatchIndex = 0, nextCmdPosition = 0;
int length = 0, repeatCount = 0;
// nothing to process
if (matchCollection.Count == 0 || level > 25)
return input.Length;
// pre-inline data
if (matchCollection[0].Index > 0)
{
nextCmdPosition = matchCollection[0].Index;
decompressedLength += matchCollection[0].Index;
}
// cycle through detected commands, ignore non-commands, include inline data
foreach (Match m in matchCollection)
{
int.TryParse(m.Groups[1].Value, out length);
int.TryParse(m.Groups[2].Value, out repeatCount);
if (m.Index >= nextCmdPosition)
{
// inline data
if (m.Index > nextCmdPosition)
decompressedLength += (m.Index - nextCmdPosition);
string payload = input.Substring(m.Index + m.Length, length);
long payloadLength = recursive ? CalcDecompressedLength(payload, true, level++) : payload.Length;
decompressedLength += (payloadLength * repeatCount);
lastMatchIndex = m.Index;
nextCmdPosition = (m.Index + m.Length) + length;
}
}
// trailing inline data
if (lastMatchIndex != nextCmdPosition)
decompressedLength += (input.Length - nextCmdPosition);
return decompressedLength;
}
public static string Decompress(string input, bool recursiveDecompress = false, int level = 0, int maxLevel = 25)
{
StringBuilder output = new StringBuilder();
MatchCollection matchCollection = Regex.Matches(input, @"\((\d+)x(\d+)\)");
int lastMatchIndex = 0, nextCmdPosition = 0;
int length = 0, repeatCount = 0;
// nothing to process or the recursion level is too high
if (matchCollection.Count == 0 || level > maxLevel)
return input;
// pre-inline data
if (matchCollection[0].Index > 0)
{
nextCmdPosition = matchCollection[0].Index;
output.Append(input.Substring(0, matchCollection[0].Index));
}
// cycle through detected commands, ignore non-commands, include inline data
foreach (Match m in matchCollection)
{
int.TryParse(m.Groups[1].Value, out length);
int.TryParse(m.Groups[2].Value, out repeatCount);
if (m.Index >= nextCmdPosition)
{
// inline data
if (m.Index > nextCmdPosition)
output.Append(input.Substring(nextCmdPosition, m.Index - nextCmdPosition));
string payload = input.Substring(m.Index + m.Length, length);
if (recursiveDecompress)
payload = Decompress(payload, true, level++);
for (int i = 0; i < repeatCount; i++)
output.Append(payload);
lastMatchIndex = m.Index;
nextCmdPosition = (m.Index + m.Length) + length;
}
}
// trailing inline data
if (lastMatchIndex != nextCmdPosition)
{
output.Append(input.Substring(nextCmdPosition, input.Length - nextCmdPosition));
}
return output.ToString();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("ADVENT"));
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("A(1x5)BC"));
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("(3x3)XYZ"));
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("A(2x2)BCD(2x2)EFG"));
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("(6x1)(1x3)A"));
Console.WriteLine("Part 1 Example Length: {0}", bscott09.CalcDecompressedLength("X(8x2)(3x3)ABCY"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("ADVENT"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("A(1x5)BC"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("(3x3)XYZ"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("A(2x2)BCD(2x2)EFG"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("(6x1)(1x3)A"));
Console.WriteLine("Part 1 Example: {0}", bscott09.Decompress("X(8x2)(3x3)ABCY"));
// Part 2
string input = File.ReadAllText("input_day09.txt").Trim();
Console.WriteLine("Part 1 Length: {0}\n", bscott09.CalcDecompressedLength(input));
Console.WriteLine("Part 2 Example Length: {0}", bscott09.CalcDecompressedLength("(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN", true));
Console.WriteLine("Part 2 Length: {0}\n", bscott09.CalcDecompressedLength(input, true));
Console.ReadLine();
}
}
}