109 lines
2.4 KiB
C
109 lines
2.4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "../../lib/aoc.h"
|
|
|
|
typedef struct Report {
|
|
int *levels;
|
|
int size;
|
|
int skip;
|
|
} Report;
|
|
|
|
bool report_increasing(Report *report) {
|
|
int current = report->levels[0];
|
|
int i = 1;
|
|
if (report->skip == 0) {
|
|
current = report->levels[1];
|
|
i = 2;
|
|
}
|
|
for (; i < report->size; i++) {
|
|
if (i == report->skip) continue;
|
|
int next = report->levels[i];
|
|
if (next <= current) return false;
|
|
current = next;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool report_decreasing(Report *report) {
|
|
int current = report->levels[0];
|
|
int i = 1;
|
|
if (report->skip == 0) {
|
|
current = report->levels[1];
|
|
i = 2;
|
|
}
|
|
for (; i < report->size; i++) {
|
|
if (i == report->skip) continue;
|
|
int next = report->levels[i];
|
|
if (next >= current) return false;
|
|
current = next;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool report_changing_slowly(Report *report) {
|
|
int current = report->levels[0];
|
|
int i = 1;
|
|
if (report->skip == 0) {
|
|
current = report->levels[1];
|
|
i = 2;
|
|
}
|
|
for (; i < report->size; i++) {
|
|
if (i == report->skip) continue;
|
|
int next = report->levels[i];
|
|
if (abs(next - current) > 3) return false;
|
|
current = next;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool report_safe_with_skips(Report *report) {
|
|
for (int i = -1; i < report->size; i++) {
|
|
report->skip = i;
|
|
if ((report_increasing(report) || report_decreasing(report)) && report_changing_slowly(report)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool report_safe(Report *report) {
|
|
report->skip = -1;
|
|
return (report_increasing(report) || report_decreasing(report)) && report_changing_slowly(report);
|
|
}
|
|
|
|
void populate_report(Report *report, char *line) {
|
|
report->size = 0;
|
|
char *level = strtok(line, " ");
|
|
while (level != NULL) {
|
|
report->levels[report->size] = atoi(level);
|
|
report->size++;
|
|
level = strtok(NULL, " ");
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
char *line;
|
|
|
|
Report report;
|
|
report.levels = malloc(20 * sizeof(int));
|
|
report.size = 0;
|
|
|
|
int safe_report_count = 0;
|
|
int safe_skip_report_count = 0;
|
|
|
|
while ((line = aoc_read_line()) != NULL) {
|
|
populate_report(&report, line);
|
|
if (report_safe(&report)) safe_report_count += 1;
|
|
if (report_safe_with_skips(&report)) safe_skip_report_count += 1;
|
|
}
|
|
|
|
printf("Part 1: %d\n", safe_report_count);
|
|
printf("Part 2: %d\n", safe_skip_report_count);
|
|
|
|
aoc_free();
|
|
return 0;
|
|
}
|