diff --git a/AOC2020/AOC2020.csproj b/AOC2020/AOC2020.csproj
index a1bba53..44ca9e1 100644
--- a/AOC2020/AOC2020.csproj
+++ b/AOC2020/AOC2020.csproj
@@ -26,4 +26,8 @@
+
+
+
+
diff --git a/AOC2020/Day04.cs b/AOC2020/Day04.cs
index 669d558..224e853 100644
--- a/AOC2020/Day04.cs
+++ b/AOC2020/Day04.cs
@@ -1,3 +1,5 @@
+using MoreLinq;
+
namespace AOC2020;
///
@@ -5,176 +7,80 @@ namespace AOC2020;
///
public sealed partial class Day04 : Day
{
- private List? _passports;
+ private List>? _passports;
public Day04() : base(2020, 4, "Passport Processing")
{
}
- public override void ProcessInput()
+ public override void ProcessInput() =>
+ _passports = Input.Split("").Select(Parse).ToList();
+
+ [GeneratedRegex("#[0-9a-f]{6}")]
+ private static partial Regex HexColor();
+
+ private static Dictionary Parse(IEnumerable list) =>
+ string.Join(' ', list).Split(' ', StringSplitOptions.TrimEntries)
+ .ToDictionary(k => k.Split(':', 2)[0], v => v.Split(':', 2)[1]);
+
+ private static bool IsValid(Dictionary d) =>
+ new[] { "byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid" }.All(d.ContainsKey);
+
+ private static bool ExtendedValidation(Dictionary d)
{
- _passports = new();
+ if (!IsValid(d)) return false;
- var a = new List();
- foreach (var line in Input)
+ // birth year
+ if (int.TryParse(d["byr"], out var byr))
{
- if (line == "")
- {
- _passports.Add(Passport.Parse(a));
- a.Clear();
- continue;
- }
-
- a.Add(line);
+ if (byr is < 1920 or > 2002) return false;
}
+ else return false;
- if (a.Any()) _passports.Add(Passport.Parse(a));
+ // issuance year
+ if (int.TryParse(d["iyr"], out var iyr))
+ {
+ if (iyr is < 2010 or > 2020) return false;
+ }
+ else return false;
+
+ // expiration year
+ if (int.TryParse(d["eyr"], out var eyr))
+ {
+ if (eyr is < 2020 or > 2030) return false;
+ }
+ else return false;
+
+ // height
+ if (d["hgt"].EndsWith("cm"))
+ {
+ if (int.TryParse(d["hgt"][..3], out var hgt))
+ {
+ if (hgt is < 150 or > 193) return false;
+ }
+ else return false;
+ }
+ else if (d["hgt"].EndsWith("in"))
+ {
+ if (int.TryParse(d["hgt"][..2], out var hgt))
+ {
+ if (hgt is < 59 or > 76) return false;
+ }
+ else return false;
+ }
+ else return false;
+
+ // hair color
+ if (!HexColor().IsMatch(d["hcl"])) return false;
+
+ // eye color
+ if (!new[] { "amb", "blu", "brn", "gry", "grn", "hzl", "oth" }.Contains(d["ecl"]))
+ return false;
+
+ // passport id
+ return !d.ContainsKey("pid") || d["pid"].Length == 9;
}
- public override object Part1() => _passports!.Count(p => p.IsValid);
-
- public override object Part2() => _passports!.Count(p => p.ExtendedValidation());
-
- private partial class Passport
- {
- private string? _byr;
- private string? _cid;
- private string? _ecl;
- private string? _eyr;
- private string? _hcl;
- private string? _hgt;
- private string? _iyr;
- private string? _pid;
-
- public bool IsValid =>
- _byr != null &&
- _iyr != null &&
- _eyr != null &&
- _hgt != null &&
- _hcl != null &&
- _ecl != null &&
- _pid != null;
-
- public bool ExtendedValidation()
- {
- if (!IsValid) return false;
-
- // birth year
- if (int.TryParse(_byr, out var byr))
- {
- if (byr is < 1920 or > 2002)
- return false;
- }
- else
- {
- return false;
- }
-
- // issuance year
- if (int.TryParse(_iyr, out var iyr))
- {
- if (iyr is < 2010 or > 2020)
- return false;
- }
- else
- {
- return false;
- }
-
- // expiration year
- if (int.TryParse(_eyr, out var eyr))
- {
- if (eyr is < 2020 or > 2030)
- return false;
- }
- else
- {
- return false;
- }
-
- // height
- if (_hgt!.EndsWith("cm"))
- {
- var h = _hgt[..3];
- if (int.TryParse(h, out var hgt))
- {
- if (hgt is < 150 or > 193)
- return false;
- }
- else
- {
- return false;
- }
- }
- else if (_hgt.EndsWith("in"))
- {
- var h = _hgt[..2];
- if (int.TryParse(h, out var hgt))
- {
- if (hgt is < 59 or > 76)
- return false;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
-
- // hair color
- if (!HexColor().IsMatch(_hcl!))
- return false;
-
- // eye color
- if (!new[] { "amb", "blu", "brn", "gry", "grn", "hzl", "oth" }.Contains(_ecl))
- return false;
-
- // passport id
- return _pid == null || _pid.Length == 9;
- }
-
- public static Passport Parse(IEnumerable list)
- {
- var passport = new Passport();
- foreach (var entry in string.Join(' ', list).Split(' ', StringSplitOptions.TrimEntries))
- {
- var spl = entry.Split(':', 2);
- switch (spl[0])
- {
- case "byr":
- passport._byr = spl[1];
- break;
- case "iyr":
- passport._iyr = spl[1];
- break;
- case "eyr":
- passport._eyr = spl[1];
- break;
- case "hgt":
- passport._hgt = spl[1];
- break;
- case "hcl":
- passport._hcl = spl[1];
- break;
- case "ecl":
- passport._ecl = spl[1];
- break;
- case "pid":
- passport._pid = spl[1];
- break;
- case "cid":
- passport._cid = spl[1];
- break;
- }
- }
-
- return passport;
- }
-
- [GeneratedRegex("#[0-9a-f]{6}")]
- private static partial Regex HexColor();
- }
-}
+ public override object Part1() => _passports!.Count(IsValid);
+ public override object Part2() => _passports!.Count(ExtendedValidation);
+}
\ No newline at end of file