-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.c
135 lines (112 loc) · 3.01 KB
/
day05.c
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// AOC 2015 solution in C
// @chadsy
// Copyright (C) 2021 Chad Royal
// MIT License http://opensource.org/licenses/MIT
//
// Day 5
// The one about applying rules to see which of the input strings are naughty
// or nice.
//
// So, there are rules about evaluating the string. There's a brute-force method
// to just check for each of the conditions (e.g. contains at least 3 unique
// vowels) on the string. That's a O(m*n*x) problem, roughly. There might be a way
// to optimize that down to just walking the string's characters and accumulating
// test results. At the start, no idea which I'll end up with.
//
// Edit: ended up using some the basic string library functions, like strchr()
// and strstr() and just tried to handle the logic with care.
//
// Fails: Part 2 is NOT 429
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
char *trim(char *str) {
char *p = str + (strlen(str) - 1);
while (isspace(*p)) {
*p-- = '\0';
}
return str;
}
bool contains_double_letter(const char *str) {
const char *p = str + 1;
char prev = *str;
while (*p) {
if (*p == prev) {
return true;
}
prev = *p++;
}
return false;
}
bool contains_three_vowels(const char *str) {
int found_count = 0;
while (*str && found_count < 3) {
if (strchr("aeiou", *str))
found_count++;
str++;
}
return found_count >= 3;
}
bool contains_blocklist(const char *str) {
return (strstr(str, "ab") ||
strstr(str, "cd") ||
strstr(str, "pq") ||
strstr(str, "xy"));
}
bool is_nice_first(const char *str) {
if (contains_double_letter(str) &&
contains_three_vowels(str) &&
!contains_blocklist(str))
return true;
else
return false;
}
bool contains_split_pair(const char *str) {
if (strlen(str) < 3)
return false;
const char *p = str + 2;
const char *prev = str;
while (*p) {
if (*p == *prev) {
return true;
}
prev++, p++;
}
return false;
}
bool contains_non_overlapping_pair_pair(const char *str) {
char pair[3];
while (*str) {
strncpy(pair, str, sizeof(pair) - 1);
if (strstr(str + 2, pair))
return true;
str++;
}
return false;
}
bool is_nice_second(const char *str) {
if (contains_split_pair(str) &&
contains_non_overlapping_pair_pair(str))
return true;
else
return false;
}
int main(int argc, char **argv) {
FILE *input = stdin;
char arg[128];
int first_nice_count = 0;
int second_nice_count = 0;
while (fgets(arg, sizeof(arg) - 1, input)) {
trim(arg);
if (is_nice_first(arg)) {
first_nice_count++;
}
if (is_nice_second(arg)) {
second_nice_count++;
}
}
printf("part 1, easy rules: found %d nice strings\n", first_nice_count);
printf("part 2, hard rules: found %d nice strings\n", second_nice_count);
return 0;
}