1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#include "aoc.h"
#include <vector>
namespace aoc2017 {
typedef bool (*match_f)(const char*, const char*);
bool match(const char* p1, const char* p2) {
auto is_az = [](char c) { return c >= 'a' && c <= 'z'; };
while (is_az(*p1) && is_az(*p2)) {
if (*p1++ != *p2++) {
return false;
}
}
return !is_az(*p1) && !is_az(*p2);
}
bool anagram(const char* p1, const char* p2) {
auto is_az = [](char c) { return c >= 'a' && c <= 'z'; };
auto len = [&is_az](const char* p, int is[]) {
const char* p0 = p;
while (is_az(*p)) {
is[int(*p - 'a')]++;
p++;
}
return p - p0;
};
int is1[26] = {0};
int is2[26] = {0};
int l1 = len(p1, is1);
int l2 = len(p2, is2);
if (l1 != l2) {
return false;
}
for (int i = 0; i < 26; i++) {
if (is1[i] != is2[i]) {
return false;
}
}
return true;
}
bool compare(size_t i, const std::vector<const char*>& ps, match_f f) {
if (i < ps.size() - 1) {
for (size_t j = i + 1; j < ps.size(); j++) {
if (f(ps[i], ps[j])) {
return false;
}
}
return compare(i + 1, ps, f);
}
return true;
}
bool is_valid(line_view lv, match_f f) {
const char* p = lv.line;
std::vector<const char*> ps;
ps.push_back(p);
while (p < lv.line + lv.length) {
if (*p == ' ') {
ps.push_back(p + 1);
}
p++;
}
return compare(0, ps, f);
}
std::pair<int, int> day4(line_view file) {
int t0{0};
int t1{0};
per_line(file, [&t0, &t1](line_view lv) {
if (is_valid(lv, match)) {
t0 += 1;
}
if (is_valid(lv, anagram)) {
t1 += 1;
}
return true;
});
return {t0, t1};
}
} // namespace aoc2017
|