commit 6e2c82f8dbd4c7ae5590e0654f5b6932867421d8
parent 808cdc3ce6e41aa17cd4e11864b1014a84151097
Author: bsandro <email@bsandro.tech>
Date: Fri, 1 Dec 2023 15:16:08 +0200
day 01 p2
Diffstat:
2 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/day01/puzzle.c b/day01/puzzle.c
@@ -6,9 +6,26 @@
#include <string.h>
#include <strings.h>
#include <assert.h>
+#include <stdbool.h>
#define STR_LEN 1024
+int get_digits_p1(const char *);
+int get_digits_p2(const char *);
+int pop_digit(const char *);
+
+bool is_digit(char b) {
+ return b>='0' && b<='9';
+}
+
+bool is_letter(char b) {
+ return b>='a' && b<='z';
+}
+
+static const char* digits[9] = {
+ "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
+};
+
void puzzle(const char *filename, long long *result1, long long *result2) {
FILE *infile = fopen(filename, "r");
if (infile == NULL) {
@@ -20,20 +37,13 @@ void puzzle(const char *filename, long long *result1, long long *result2) {
unsigned int line_num = 0;
*result1 = 0;
+ *result2 = 0;
while (fgets(buf, STR_LEN, infile) != NULL) {
- int len = strlen(buf);
- int n1 = -1, n2 = -1;
- for (int i=0; i < len; ++i) {
- char b = buf[i];
- if (b > 47 && b < 58) {
- n2 = b-48;
- if (n1==-1) n1=b-48;
- }
- }
- int num = n1*10 + n2;
- //printf("num:%d\n", num);
- *result1 += num;
+ int num1 = get_digits_p1(buf);
+ int num2 = get_digits_p2(buf);
+ *result1 += num1;
+ *result2 += num2;
++line_num;
bzero(buf, STR_LEN);
}
@@ -42,4 +52,63 @@ void puzzle(const char *filename, long long *result1, long long *result2) {
fclose(infile);
(void)result2;
+ (void)digits;
+}
+
+int get_digits_p1(const char *str) {
+ int len = strlen(str);
+ int n1 = -1, n2 = -1;
+ for (int i=0; i<len; ++i) {
+ char b = str[i];
+ if (is_digit(b)) {
+ n2 = b-'0';
+ if (n1==-1) n1=b-'0';
+ }
+ }
+ return n1*10+n2;
+}
+
+int get_digits_p2(const char *str) {
+ (void)str;
+
+ int len = strlen(str);
+ int n1=-1, n2=-1, i=0;
+ (void)n2;
+ while (i<len) {
+ char b = str[i];
+ if (is_digit(b)) {
+ n2 = b-'0';
+ if (n1==-1) n1=b-'0';
+ ++i;
+ } else if (is_letter(b)) {
+ int di = pop_digit(str+i);
+ if (di==-1) {
+ ++i;
+ } else {
+ n2=di+1;
+ if (n1==-1) n1=n2;
+ //printf("(%d) found digit %d (%s) (len %d of %d) in %s (full %s)\n", i, di+1, digits[di], d_len, len, str+i, str);
+
+ // initial screwup, test was working but real data did not because of overlaps:)
+ //i+=d_len;
+ ++i;
+ }
+ } else {
+ ++i;
+ }
+ }
+
+ return n1*10+n2;
+}
+
+int pop_digit(const char *str) {
+ int len2 = strlen(str);
+ for (int i=0; i<9; ++i) {
+ int len1 = strlen(digits[i]);
+ if (len2<len1) continue;
+ if (strncmp(digits[i], str, len1) == 0) {
+ return i;
+ }
+ }
+ return -1;
}
diff --git a/day01/test1.txt b/day01/test1.txt
@@ -0,0 +1,7 @@
+two1nine
+eightwothree
+abcone2threexyz
+xtwone3four
+4nineeightseven2
+zoneight234
+7pqrstsixteen