aboutsummaryrefslogtreecommitdiff
path: root/2020/src/day04.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2024-01-04 23:30:17 +0100
committerThomas Schmucker <ts@its1.de>2024-01-04 23:30:17 +0100
commit1f93e69adfbe8830c0ef47a24e07a7f333168dd4 (patch)
tree697a5554f296f8776fe1bb8e32370dc8558e619f /2020/src/day04.cpp
parentd73937c6977a7cb6b2516ba662495ef662fd3fb0 (diff)
downloadadvent-of-code-1f93e69adfbe8830c0ef47a24e07a7f333168dd4.tar.gz
advent-of-code-1f93e69adfbe8830c0ef47a24e07a7f333168dd4.tar.bz2
advent-of-code-1f93e69adfbe8830c0ef47a24e07a7f333168dd4.zip
solution for day 4
Diffstat (limited to '2020/src/day04.cpp')
-rw-r--r--2020/src/day04.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/2020/src/day04.cpp b/2020/src/day04.cpp
new file mode 100644
index 0000000..63f8c92
--- /dev/null
+++ b/2020/src/day04.cpp
@@ -0,0 +1,132 @@
1#include <algorithm>
2#include <array>
3#include <fstream>
4#include <iostream>
5#include <iterator>
6#include <map>
7#include <sstream>
8#include <string>
9#include <vector>
10using namespace std;
11
12auto
13split(string_view line, string_view delimiter)
14{
15 size_t pos_start = 0;
16 size_t pos_end = 0;
17
18 vector<string> res;
19
20 while ( (pos_end = line.find(delimiter, pos_start)) != string::npos ) {
21 auto token = line.substr(pos_start, pos_end - pos_start);
22 pos_start = pos_end + delimiter.length();
23
24 res.emplace_back(token);
25 }
26
27 if ( pos_start != line.size() ) {
28 res.emplace_back(line.substr(pos_start));
29 }
30 return res;
31}
32
33auto
34read_file(string_view filename)
35{
36 fstream input{ filename };
37 const auto passports = split(string{ istreambuf_iterator<char>{ input }, istreambuf_iterator<char>{} }, "\n\n");
38
39 vector<map<string, string>> result;
40
41 for ( const auto& passport: passports ) {
42 map<string, string> bar;
43 stringstream foo{ passport };
44 for ( string keyval; foo >> keyval; ) {
45 auto colon = keyval.find(':');
46 auto key = keyval.substr(0, colon);
47 auto val = keyval.substr(colon + 1);
48 bar[key] = val;
49 }
50 result.emplace_back(bar);
51 }
52
53 return result;
54}
55
56auto
57contains_all_fields(const map<string, string>& passport)
58{
59 static const array<string, 7> keys = { "byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid" };
60 return all_of(keys.begin(), keys.end(), [&](auto key) { return passport.contains(key); });
61}
62
63void
64part1(const vector<map<string, string>>& passports)
65{
66 cout << count_if(passports.begin(), passports.end(), contains_all_fields) << endl;
67}
68
69void
70part2(const vector<map<string, string>>& passports)
71{
72 auto check_birth_year = [](const map<string, string>& passport) {
73 auto year = stoi(passport.at("byr"));
74 return 1920 <= year && year <= 2002;
75 };
76
77 auto check_issue_year = [](const map<string, string>& passport) {
78 auto year = stoi(passport.at("iyr"));
79 return 2010 <= year && year <= 2020;
80 };
81
82 auto check_expiration_year = [](const map<string, string>& passport) {
83 auto year = stoi(passport.at("eyr"));
84 return 2020 <= year && year <= 2030;
85 };
86
87 auto check_height = [](const map<string, string>& passport) {
88 auto height_str = passport.at("hgt");
89 auto height = stoi(height_str);
90 return (height_str.ends_with("in") && 59 <= height && height <= 76) ||
91 (height_str.ends_with("cm") && 150 <= height && height <= 193);
92 };
93
94 auto check_hair_color = [](const map<string, string>& passport) {
95 auto hair = passport.at("hcl");
96 return hair.length() == 7 && hair.starts_with('#') && hair.find_first_not_of("0123456789abcdef", 1) == string::npos;
97 };
98
99 auto check_eye_color = [](const map<string, string>& passport) {
100 const array<string, 7> valid = { "amb", "blu", "brn", "gry", "grn", "hzl", "oth" };
101 return find(valid.begin(), valid.end(), passport.at("ecl")) != valid.end();
102 };
103
104 auto check_passport_id = [](const map<string, string>& passport) {
105 auto pid = passport.at("pid");
106 return pid.length() == 9 && pid.find_first_not_of("0123456789") == string::npos;
107 };
108
109 const array<function<bool(const map<string, string>&)>, 8> checks = {
110 contains_all_fields,
111 check_birth_year,
112 check_issue_year,
113 check_expiration_year,
114 check_height,
115 check_hair_color,
116 check_eye_color,
117 check_passport_id
118 };
119
120 cout << count_if(passports.begin(), passports.end(), [&checks](const map<string, string>& passport) {
121 return all_of(checks.begin(), checks.end(), [&passport](auto check) { return check(passport); });
122 }) << endl;
123}
124
125int
126main()
127{
128 auto passports = read_file("data/day04.txt");
129
130 part1(passports);
131 part2(passports);
132}