aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-12-21 21:43:43 +0800
committerMistivia <i@mistivia.com>2025-12-21 21:43:43 +0800
commit068ef825478d0d458f50057f572a45c59b2cb9ca (patch)
tree820ac00930c42f5af3c0ee6ca59f2299bd355606
parent5eb6bd32ca4102bf29c7fabd26984c1c7c351c1e (diff)
day 5 part 2
-rw-r--r--05/Makefile4
-rw-r--r--05/part2.c150
2 files changed, 152 insertions, 2 deletions
diff --git a/05/Makefile b/05/Makefile
index a8f700f..7d325ba 100644
--- a/05/Makefile
+++ b/05/Makefile
@@ -1,10 +1,10 @@
all: part1 part2
part1: part1.c
- gcc -g part1.c -o part1 -lalgds
+ gcc -Wall -g part1.c -o part1 -lalgds
part2: part2.c
- gcc -g part2.c -o part2 -lalgds
+ gcc -Wall -g part2.c -o part2 -lalgds
1: part1
cat input | ./part1
diff --git a/05/part2.c b/05/part2.c
index e69de29..f7939f2 100644
--- a/05/part2.c
+++ b/05/part2.c
@@ -0,0 +1,150 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <algds/vec.h>
+#include <algds/str.h>
+#include <algds/sort.h>
+#include <stdlib.h>
+
+#define PANIC do { \
+ fprintf(stderr, "panic at %s:%d\n", __FILE__, __LINE__); \
+ abort(); \
+} while (0)
+
+void expect_char(char e) {
+ int c = fpeek(stdin);
+ if (c != e) {
+ PANIC;
+ }
+ fgetc(stdin);
+}
+
+void skip_space() {
+ while (1) {
+ int c = fpeek(stdin);
+ if (c == EOF) return;
+ if (isspace(c)) {
+ fgetc(stdin);
+ } else {
+ return;
+ }
+ }
+}
+
+bool string2long(const char *s, long *num) {
+ char *end;
+ errno = 0;
+ *num = strtol(s, &end, 10);
+ if (end == s) {
+ return false;
+ }
+ if (errno != 0) {
+ return false;
+ }
+ return true;
+}
+
+int64_t parse_integer() {
+ long ret;
+ StrBuilder sb;
+ StrBuilder_init(&sb);
+ while (1) {
+ int c = fpeek(stdin);
+ if (isdigit(c)) {
+ fgetc(stdin);
+ StrBuilder_append_char(&sb, c);
+ } else {
+ break;
+ }
+ }
+ if (strlen(sb.buf) == 0) {
+ PANIC;
+ }
+ StrBuilder_append_char(&sb, '\0');
+ if (!string2long(sb.buf, &ret)) {
+ PANIC;
+ }
+ free(sb.buf);
+ return ret;
+}
+
+typedef struct {
+ int64_t start;
+ int64_t end;
+} Range;
+
+void Range_show(Range self, FILE *fp) {
+ fprintf(fp, "%ld-%ld", self.start, self.end);
+}
+
+VECTOR_DEF(Range)
+VECTOR_IMPL(Range)
+
+Range parse_range() {
+ Range ret;
+ ret.start = parse_integer();
+ expect_char('-');
+ ret.end = parse_integer();
+ expect_char('\n');
+ return ret;
+}
+
+
+int Range_cmp(Range a, Range b) {
+ if (a.start < b.start) {
+ return -1;
+ } else if (a.start == b.start) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+QSORT_DEF(Range)
+QSORT_IMPL(Range)
+
+int main() {
+ RangeVector ranges, unioned;
+ RangeVector_init(&ranges);
+ RangeVector_init(&unioned);
+ int c;
+ while (1) {
+ c = fpeek(stdin);
+ if (c == '\n') {
+ break;
+ } else if (isdigit(c)) {
+ Range r = parse_range();
+ RangeVector_push_back(&ranges, r);
+ } else {
+ PANIC;
+ }
+ }
+ expect_char('\n');
+ Range_qsort(ranges.buffer, RangeVector_len(&ranges));
+ if (RangeVector_len(&ranges) < 1) {
+ PANIC;
+ }
+ Range current = ranges.buffer[0];
+ for (int i = 1; i < RangeVector_len(&ranges); i++) {
+ if (ranges.buffer[i].start > current.end) {
+ RangeVector_push_back(&unioned, current);
+ current = ranges.buffer[i];
+ continue;
+ } else if (ranges.buffer[i].end > current.end) {
+ current.end = ranges.buffer[i].end;
+ }
+ }
+ RangeVector_push_back(&unioned, current);
+ long res = 0;
+ for (int i = 0; i < RangeVector_len(&unioned); i++) {
+ Range cur = unioned.buffer[i];
+ res += cur.end - cur.start + 1;
+ }
+ printf("%ld\n", res);
+
+ RangeVector_free(&ranges);
+ RangeVector_free(&unioned);
+ return 0;
+} \ No newline at end of file