Colin McMillen
4 years ago
3 changed files with 1332 additions and 1 deletions
-
1932020/Day04.cs
-
22020/Program.cs
-
11382020/day04.txt
@ -0,0 +1,193 @@ |
|||
using System; |
|||
using static System.Console; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Text.RegularExpressions; |
|||
using Xunit; |
|||
|
|||
namespace AdventOfCode { |
|||
|
|||
public class Day04 { |
|||
|
|||
static string[] requiredFields = { |
|||
// "cid" not required because we are hackers
|
|||
"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid" |
|||
}; |
|||
|
|||
static string[] validEyeColors = { |
|||
"amb", "blu", "brn", "gry", "grn", "hzl", "oth" |
|||
}; |
|||
|
|||
static bool IsValidPassport1(string input) { |
|||
string[] fields = input.Split(' '); |
|||
var fieldsPresent = new HashSet<string>(); |
|||
foreach (string field in fields) { |
|||
string[] tokens = field.Split(':'); |
|||
string key = tokens[0]; |
|||
fieldsPresent.Add(key); |
|||
} |
|||
return fieldsPresent.IsSupersetOf(requiredFields); |
|||
} |
|||
|
|||
static int ParseInt(string value) { |
|||
int result; |
|||
if (!int.TryParse(value, out result)) { |
|||
return -1; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
static bool IsValidPassport2(string input) { |
|||
string[] fields = input.Split(' '); |
|||
var fieldsPresent = new HashSet<string>(); |
|||
foreach (string field in fields) { |
|||
if (field.Length == 0) { |
|||
continue; |
|||
} |
|||
string[] tokens = field.Split(':'); |
|||
string key = tokens[0]; |
|||
string value = tokens[1]; |
|||
fieldsPresent.Add(key); |
|||
if (key == "byr") { |
|||
int year = ParseInt(value); |
|||
if (year < 1920 || year > 2002) { |
|||
return false; |
|||
} |
|||
} else if (key == "iyr") { |
|||
int year = ParseInt(value); |
|||
if (year < 2010 || year > 2020) { |
|||
return false; |
|||
} |
|||
} else if (key == "eyr") { |
|||
int year = ParseInt(value); |
|||
if (year < 2020 || year > 2030) { |
|||
return false; |
|||
} |
|||
} else if (key == "hgt") { |
|||
string unit = value.Substring(value.Length - 2); |
|||
int amount = ParseInt(value.Substring(0, value.Length - 2)); |
|||
if (unit == "cm") { |
|||
if (amount < 150 || amount > 193) { |
|||
return false; |
|||
} |
|||
} else if (unit == "in") { |
|||
if (amount < 59 || amount > 76) { |
|||
return false; |
|||
} |
|||
} else { // not cm or in
|
|||
return false; |
|||
} |
|||
} else if (key == "hcl") { |
|||
Regex color = new Regex(@"^#[0-9a-f]{6}$"); |
|||
if (!color.IsMatch(value)) { |
|||
return false; |
|||
} |
|||
} else if (key == "ecl") { |
|||
if (!validEyeColors.Contains(value)) { |
|||
return false; |
|||
} |
|||
} else if (key == "pid") { |
|||
Regex pid = new Regex(@"^[0-9]{9}$"); |
|||
if (!pid.IsMatch(value)) { |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
return fieldsPresent.IsSupersetOf(requiredFields); |
|||
} |
|||
|
|||
static List<string> ParsePassports(string[] input) { |
|||
var result = new List<string>(); |
|||
string passport = ""; |
|||
foreach (string line in input) { |
|||
if (line == "") { |
|||
result.Add(passport); |
|||
passport = ""; |
|||
} else { |
|||
passport += line + " "; |
|||
} |
|||
} |
|||
result.Add(passport); |
|||
return result; |
|||
} |
|||
|
|||
static int CountValidPassports1(string[] input) { |
|||
return ParsePassports(input).Count(IsValidPassport1); |
|||
} |
|||
|
|||
static int CountValidPassports2(string[] input) { |
|||
return ParsePassports(input).Count(IsValidPassport2); |
|||
} |
|||
|
|||
static int Part1() { |
|||
string[] input = File.ReadAllLines(Util.RootDir + "day04.txt"); |
|||
return CountValidPassports1(input); |
|||
} |
|||
|
|||
static int Part2() { |
|||
string[] input = File.ReadAllLines(Util.RootDir + "day04.txt"); |
|||
return CountValidPassports2(input); |
|||
} |
|||
|
|||
[Fact] |
|||
public static void Test() { |
|||
string[] example = |
|||
@"ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
|
|||
byr:1937 iyr:2017 cid:147 hgt:183cm |
|||
|
|||
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 |
|||
hcl:#cfa07d byr:1929 |
|||
|
|||
hcl:#ae17e1 iyr:2013 |
|||
eyr:2024 |
|||
ecl:brn pid:760753108 byr:1931 |
|||
hgt:179cm |
|||
|
|||
hcl:#cfa07d eyr:2025 pid:166559648 |
|||
iyr:2011 ecl:brn hgt:59in".Split('\n');
|
|||
|
|||
Assert.Equal(2, CountValidPassports1(example)); |
|||
Assert.Equal(256, Part1()); |
|||
|
|||
string[] invalidPassports = |
|||
@"eyr:1972 cid:100
|
|||
hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 |
|||
|
|||
iyr:2019 |
|||
hcl:#602927 eyr:1967 hgt:170cm |
|||
ecl:grn pid:012533040 byr:1946 |
|||
|
|||
hcl:dab227 iyr:2012 |
|||
ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 |
|||
|
|||
hgt:59cm ecl:zzz |
|||
eyr:2038 hcl:74454a iyr:2023 |
|||
pid:3556412378 byr:2007".Split('\n');
|
|||
|
|||
string[] validPassports = |
|||
@"pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
|
|||
hcl:#623a2f |
|||
|
|||
eyr:2029 ecl:blu cid:129 byr:1989 |
|||
iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm |
|||
|
|||
hcl:#888785 |
|||
hgt:164cm byr:2001 iyr:2015 cid:88 |
|||
pid:545766238 ecl:hzl |
|||
eyr:2022 |
|||
|
|||
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719".Split('\n');
|
|||
|
|||
List<string> invalid = ParsePassports(invalidPassports); |
|||
Assert.Equal(4, invalid.Count); |
|||
Assert.All(invalid, item => Assert.False(IsValidPassport2(item))); |
|||
|
|||
List<string> valid = ParsePassports(validPassports); |
|||
Assert.Equal(4, valid.Count); |
|||
Assert.All(valid, item => Assert.True(IsValidPassport2(item))); |
|||
|
|||
Assert.Equal(198, Part2()); |
|||
} |
|||
} |
|||
} |
1138
2020/day04.txt
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue