244 lines
6.5 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|