diff --git a/AOC.Test/Test2016.cs b/AOC.Test/Test2016.cs
index a7742ce..dca7af7 100644
--- a/AOC.Test/Test2016.cs
+++ b/AOC.Test/Test2016.cs
@@ -9,6 +9,7 @@ public class Test2016
[DataRow(typeof(Day01), "300", "159")]
[DataRow(typeof(Day02), "76792", "A7AC3")]
[DataRow(typeof(Day03), "993", "1849")]
+ [DataRow(typeof(Day04), "361724", "482")]
public void CheckAllDays(Type dayType, string part1, string part2)
{
Common.CheckDay(dayType, part1, part2);
diff --git a/AOC2016/Day04.cs b/AOC2016/Day04.cs
index 066d29c..1d10b8e 100644
--- a/AOC2016/Day04.cs
+++ b/AOC2016/Day04.cs
@@ -3,13 +3,45 @@ namespace AOC2016;
///
/// Day 4:
///
-public sealed class Day04() : Day(2016, 4, "Puzzle Name")
+public sealed class Day04() : Day(2016, 4, "Security Through Obscurity")
{
- public override void ProcessInput()
+ private List _rooms = null!;
+
+ private record Room(string Name, int SectorId, string Checksum)
{
+ public static Room FromRawLine(string raw)
+ {
+ var s = raw.Split('[');
+ var s2 = s[0].Split('-');
+ return new(string.Join("", s2[..^1]).Replace("-", string.Empty), int.Parse(s2.Last()), s[1].TrimEnd(']'));
+ }
+
+ public bool IsRealRoom() =>
+ Name.GroupBy(c => c)
+ .OrderByDescending(c => c.Count())
+ .ThenBy(c => c.Key)
+ .Take(5)
+ .Select(c => c.Key)
+ .ToArray()
+ .SequenceEqual(Checksum.ToCharArray());
+
+ public string DecryptedName()
+ {
+ var answer = Name.ToCharArray();
+ for (var i = 0; i < Name.Length; i++)
+ for (var l = 0; l < SectorId % 26; l++)
+ answer[i] = answer[i] == 'z' ? 'a' : (char)(answer[i] + 1);
+
+ return new(answer);
+ }
}
- public override object Part1() => "";
+ public override void ProcessInput()
+ {
+ _rooms = Input.Select(Room.FromRawLine).ToList();
+ }
- public override object Part2() => "";
-}
+ public override object Part1() => _rooms.Where(r => r.IsRealRoom()).Sum(r => r.SectorId);
+
+ public override object Part2() => _rooms.Single(r => r.DecryptedName().Contains("northpole")).SectorId;
+}
\ No newline at end of file