day4: solfe part 1 & 2
This commit is contained in:
parent
396cc056ac
commit
d63da28b74
4 changed files with 2454 additions and 0 deletions
1133
day4/part1/input
Normal file
1133
day4/part1/input
Normal file
File diff suppressed because it is too large
Load diff
50
day4/part1/main.d
Normal file
50
day4/part1/main.d
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
module day4.part1 copy.main;
|
||||||
|
|
||||||
|
import std;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
readText("input").parsePassports.countValidPassports.writeln;
|
||||||
|
}
|
||||||
|
|
||||||
|
alias Passport = string[string];
|
||||||
|
|
||||||
|
auto parsePassports(string input)
|
||||||
|
{
|
||||||
|
return input.splitter("\n\n").map!(passport => passport.splitter().map!((entry) {
|
||||||
|
auto keyAndValue = entry.split(':');
|
||||||
|
return tuple(keyAndValue[0], keyAndValue[1]);
|
||||||
|
}).assocArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum requiredFields = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"];
|
||||||
|
|
||||||
|
bool isValidPassport(Passport passport)
|
||||||
|
{
|
||||||
|
return requiredFields.all!(field => field in passport);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto countValidPassports(R)(R r) if (isInputRange!R && is(ElementType!R == Passport))
|
||||||
|
{
|
||||||
|
return r.filter!isValidPassport.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
auto input = `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`;
|
||||||
|
|
||||||
|
auto passPorts = input.parsePassports;
|
||||||
|
assert(passPorts.countValidPassports == 2);
|
||||||
|
}
|
1133
day4/part2/input
Normal file
1133
day4/part2/input
Normal file
File diff suppressed because it is too large
Load diff
138
day4/part2/main.d
Normal file
138
day4/part2/main.d
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
module day4.part2.main;
|
||||||
|
|
||||||
|
import std;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
readText("input").parsePassports.countValidPassports.writeln;
|
||||||
|
}
|
||||||
|
|
||||||
|
alias Passport = string[string];
|
||||||
|
|
||||||
|
auto parsePassports(string input)
|
||||||
|
{
|
||||||
|
return input.splitter("\n\n").map!(passport => passport.splitter().map!((entry) {
|
||||||
|
auto keyAndValue = entry.split(':');
|
||||||
|
return tuple(keyAndValue[0], keyAndValue[1]);
|
||||||
|
}).assocArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Field : string
|
||||||
|
{
|
||||||
|
birthYear = "byr",
|
||||||
|
issueYear = "iyr",
|
||||||
|
expirationYear = "eyr",
|
||||||
|
height = "hgt",
|
||||||
|
hairColor = "hcl",
|
||||||
|
eyeColor = "ecl",
|
||||||
|
passportID = "pid",
|
||||||
|
countryID = "cid",
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidYear(int min, int max)(string yr)
|
||||||
|
{
|
||||||
|
if (yr.length != 4 || yr.canFind!(not!isDigit))
|
||||||
|
return false;
|
||||||
|
auto year = yr.to!int;
|
||||||
|
return year >= min && year <= max;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
alias isValidBirthYear = isValidYear!(1920, 2002);
|
||||||
|
alias isValidIssueYear = isValidYear!(2010, 2020);
|
||||||
|
alias isValidExpirationYear = isValidYear!(2020, 2030);
|
||||||
|
|
||||||
|
bool isValidHeight(string hgt)
|
||||||
|
{
|
||||||
|
auto match = hgt.matchFirst(r"^(\d+)(cm|in)$");
|
||||||
|
if (!match || match.length != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto number = match[1].to!int;
|
||||||
|
switch (match[2])
|
||||||
|
{
|
||||||
|
case "cm":
|
||||||
|
return number >= 150 && number <= 193;
|
||||||
|
break;
|
||||||
|
case "in":
|
||||||
|
return number >= 59 && number <= 76;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidHairColor(string hcl)
|
||||||
|
{
|
||||||
|
return hcl.matchFirst(r"^#[0-9a-f]{6}$").to!bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidEyeColor(string ecl)
|
||||||
|
{
|
||||||
|
return ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"].canFind(ecl);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidPassportID(string pid)
|
||||||
|
{
|
||||||
|
return pid.matchFirst(r"^\d{9}$").to!bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum requiredFields = [
|
||||||
|
Field.birthYear, Field.issueYear, Field.expirationYear, Field.height,
|
||||||
|
Field.hairColor, Field.eyeColor, Field.passportID
|
||||||
|
];
|
||||||
|
|
||||||
|
bool isValidPassport(Passport passport)
|
||||||
|
{
|
||||||
|
return requiredFields.all!(field => field in passport)
|
||||||
|
&& isValidBirthYear(passport[Field.birthYear])
|
||||||
|
&& isValidIssueYear(passport[Field.issueYear])
|
||||||
|
&& isValidExpirationYear(passport[Field.expirationYear])
|
||||||
|
&& isValidHeight(passport[Field.height])
|
||||||
|
&& isValidHairColor(passport[Field.hairColor])
|
||||||
|
&& isValidEyeColor(passport[Field.eyeColor])
|
||||||
|
&& isValidPassportID(passport[Field.passportID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto countValidPassports(R)(R r) if (isInputRange!R && is(ElementType!R == Passport))
|
||||||
|
{
|
||||||
|
return r.filter!isValidPassport.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
auto input = `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`;
|
||||||
|
|
||||||
|
auto passPorts = input.parsePassports;
|
||||||
|
assert(passPorts.countValidPassports == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
auto input = `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`;
|
||||||
|
|
||||||
|
auto passPorts = input.parsePassports;
|
||||||
|
assert(passPorts.countValidPassports == 4);
|
||||||
|
}
|
Loading…
Reference in a new issue