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

244 lines
6.5 KiB
C#

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Net.Mail;
namespace Day03CSharp
{
internal class Program
{
static int GetValue(char c)
{
if (c >= 'a' && c <= 'z')
{
return (int)c - (int)'a' + 1;
}
else if (c >= 'A' && c <= 'Z')
{
return (int)c - (int)'A' + 27;
}
else
{
throw new InvalidDataException("Compartment contains character that isnt an ascii english letter");
}
}
class Rucksack
{
public Dictionary<char, int> left = new Dictionary<char, int>();
public Dictionary<char, int> right = new Dictionary<char, int>();
public Rucksack()
{
}
public Rucksack(string line)
{
if (line.Length % 2 != 0)
{
throw new ArgumentException("string used to load rucksack isnt even in length");
}
var fillFunc = delegate (char c, Dictionary<char, int> dict)
{
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
{
throw new ArgumentOutOfRangeException("Input isn't a<->z or A<->Z");
}
if (!dict.ContainsKey(c))
{
dict.Add(c, 0);
}
dict[c]++;
};
// fill the left compartment
for (int i = 0; i < line.Length / 2; i++)
{
fillFunc(line[i], left);
}
// fill the right
for (int i = line.Length / 2; i < line.Length; i++)
{
fillFunc(line[i], right);
}
}
public char Duplicate
{
get
{
foreach (var c in left.Keys)
{
if (right.ContainsKey(c))
{
return c;
}
}
throw new InvalidDataException("Left and right compartment are missing a duplicate character");
}
}
public int DuplicateValue
{
get
{
return GetValue(Duplicate);
}
}
public bool Contains(char c)
{
return left.ContainsKey(c) || right.ContainsKey(c);
}
public List<char> Keys
{
get
{
var list = new List<char>();
foreach (var c in left.Keys)
{
list.Add(c);
}
foreach(var c in right.Keys)
{
if (!list.Contains(c))
{
list.Add(c);
}
}
list.Sort();
return list;
}
}
}
static List<Rucksack> GetRucksacks(string fileName)
{
List<Rucksack> list = new List<Rucksack>();
using (StreamReader reader = File.OpenText(fileName))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Rucksack r = new Rucksack(line);
list.Add(r);
}
}
return list;
}
/****************************************
// part 01
*/
static void Part01(string fileName)
{
var list = GetRucksacks(fileName);
// We have all the rucksacks, add up the stuff
int sum = 0;
foreach (var r in list)
{
sum += r.DuplicateValue;
}
Console.WriteLine("Priority Sum: " + sum);
}
/****************************************
// Part 02
*/
class Group
{
public Group() { }
public Rucksack[] rucksacks = new Rucksack[3];
public char Duplicate
{
get
{
var list = rucksacks[0].Keys;
foreach (var key in list)
{
if (rucksacks[1].Contains(key) && rucksacks[2].Contains(key))
{
return key;
}
}
throw new InvalidDataException();
}
}
public int DuplicateValue
{
get
{
return GetValue(Duplicate);
}
}
}
static List<Group> GetGroups(string fileName)
{
var list = GetRucksacks(fileName);
if (list.Count % 3 != 0)
{
throw new InvalidDataException("List of rucksacks isn't divisible by 3, cant create groups");
}
List<Group> groups = new List<Group>();
for (int i = 0; i < list.Count; i+=3)
{
var group = new Group();
group.rucksacks[0] = list[i+0];
group.rucksacks[1] = list[i+1];
group.rucksacks[2] = list[i+2];
groups.Add(group);
}
return groups;
}
static void Part02(string fileName)
{
var groups = GetGroups(fileName);
int sum = 0;
foreach (var group in groups)
{
sum += group.DuplicateValue;
}
Console.WriteLine("Group Priority: " + sum);
}
static void Main(string[] args)
{
//const string fileName = @"example-input01.txt";
const string fileName = @"puzzle-input01.txt";
Part01(fileName);
Part02(fileName);
}
}
}