advent2023

Advent of Code 2023 solutions
git clone git://bsandro.tech/advent2023
Log | Files | Refs | LICENSE

commit 6e2c82f8dbd4c7ae5590e0654f5b6932867421d8
parent 808cdc3ce6e41aa17cd4e11864b1014a84151097
Author: bsandro <email@bsandro.tech>
Date:   Fri,  1 Dec 2023 15:16:08 +0200

day 01 p2

Diffstat:
Mday01/puzzle.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Aday01/test1.txt | 7+++++++
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