2020-12-02 16:53:43 +00:00
|
|
|
import std.algorithm;
|
|
|
|
import std.format;
|
2020-12-02 17:22:20 +00:00
|
|
|
import std.functional;
|
2020-12-02 16:53:43 +00:00
|
|
|
import std.stdio;
|
2020-12-05 11:16:58 +00:00
|
|
|
import std.variant;
|
2020-12-02 16:53:43 +00:00
|
|
|
|
|
|
|
import dayutil;
|
|
|
|
|
2020-12-05 11:16:58 +00:00
|
|
|
Variant run(int day, File input, string[] args) {
|
|
|
|
auto lines = input.byLine;
|
|
|
|
Variant count = parts!ulong(day,
|
|
|
|
() => lines.count!(l => isPasswordValid1(l)),
|
|
|
|
() => lines.count!(l => isPasswordValid2(l)));
|
|
|
|
return count;
|
2020-12-02 17:22:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Part 1
|
|
|
|
bool isPasswordValid1(T)(T line) {
|
2020-12-02 16:53:43 +00:00
|
|
|
int min, max;
|
|
|
|
char c;
|
|
|
|
string password;
|
|
|
|
line.formattedRead("%d-%d %c: %s", min, max, c, password);
|
|
|
|
ulong charCount = password.count(c);
|
|
|
|
return min <= charCount && charCount <= max;
|
|
|
|
}
|
|
|
|
|
2020-12-02 17:22:20 +00:00
|
|
|
unittest {
|
|
|
|
assert(isPasswordValid1("1-3 a: abcde") == true);
|
|
|
|
assert(isPasswordValid1("1-3 b: cdefg") == false);
|
|
|
|
assert(isPasswordValid1("2-9 c: ccccccccc") == true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Part 2
|
|
|
|
bool isPasswordValid2(T)(T line) {
|
|
|
|
int min, max;
|
|
|
|
char c;
|
|
|
|
string password;
|
|
|
|
line.formattedRead("%d-%d %c: %s", min, max, c, password);
|
|
|
|
// 1 2 | R
|
|
|
|
// T T | F
|
|
|
|
// T F | T
|
|
|
|
// F T | T
|
|
|
|
// F F | F
|
|
|
|
return (password[min - 1] == c) != (password[max - 1] == c);
|
2020-12-02 16:53:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unittest {
|
2020-12-02 17:22:20 +00:00
|
|
|
assert(isPasswordValid2("1-3 a: abcde") == true);
|
|
|
|
assert(isPasswordValid2("1-3 b: cdefg") == false);
|
|
|
|
assert(isPasswordValid2("2-9 c: ccccccccc") == false);
|
2020-12-02 16:53:43 +00:00
|
|
|
}
|