diff --git a/Makefile b/Makefile index f30a7f9..b16408e 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ day2: day2/p1.c day2/p2.c day3: day3/p1.c day3/p2.c ${CC} ${CFLAGS} $@/p1.c -o bin/$@p1 -# ${CC} ${CFLAGS} $@/p2.c -o bin/$@p2 + ${CC} ${CFLAGS} $@/p2.c -o bin/$@p2 clean: rm -f bin/day*p* \ No newline at end of file diff --git a/day3/p2.c b/day3/p2.c new file mode 100644 index 0000000..1795cd1 --- /dev/null +++ b/day3/p2.c @@ -0,0 +1,115 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +int32_t parse_number(char **engine, ssize_t i, ssize_t j); + +int main(int argc, char **argv) { + FILE *input; + char *line = NULL; + size_t line_length = 0; + + if (argc == 1 || argv[1][0] == '-') + input = stdin; + else if ((input = fopen(argv[1], "r")) == NULL) { + printf("Cannot open file %s\n", argv[1]); + return -1; + } + + char **engine = NULL; + ssize_t engine_line_size = 0; + ssize_t engine_lines = 0; + + while (getline(&line, &line_length, input) != -1) { + ssize_t len = strlen(line)-1; + if (engine == NULL) { + engine = (char **) calloc(len, sizeof(char*)); + engine_line_size = len; + } + + engine[engine_lines] = (char*) calloc(len, sizeof(char)); + memcpy(engine[engine_lines], line, len); + ++engine_lines; + + memset(line, 0, line_length); + } + + int32_t part_number = 0; + + for (ssize_t i = engine_lines-1; i >= 0; --i) { + for (ssize_t j = engine_line_size-1; j >= 0; --j) { + if (engine[i][j] != '*') + continue; + + int32_t n = 1; + int8_t p = 0; + + if (isdigit(engine[i][j+1])) { + n *= parse_number(engine, i, j+1); + p++; + } + if (isdigit(engine[i][j-1])) { + n *= parse_number(engine, i, j-1); + p++; + } + + if (isdigit(engine[i+1][j])) { + n *= parse_number(engine, i+1, j); + p++; + } else { + if (isdigit(engine[i+1][j+1])) { + n *= parse_number(engine, i+1, j+1); + p++; + } + if (isdigit(engine[i+1][j-1])) { + n *= parse_number(engine, i+1, j-1); + p++; + } + } + + if (isdigit(engine[i-1][j])) { + n *= parse_number(engine, i-1, j); + p++; + } else { + if (isdigit(engine[i-1][j+1])) { + n *= parse_number(engine, i-1, j+1); + p++; + } + if (isdigit(engine[i-1][j-1])) { + n *= parse_number(engine, i-1, j-1); + p++; + } + } + + if (p >= 2) + part_number += n; + } + } + + for (ssize_t i = 0; i < engine_lines; ++i) + free(engine[i]); + free(engine); + + printf("%d\n", part_number); + + return 0; +} + +int32_t parse_number(char **engine, ssize_t i, ssize_t j) { + int32_t n = 0; + int32_t multiplier = 1; + + while (isdigit(engine[i][j+1])) j++; + + while (isdigit(engine[i][j])) { + n += (engine[i][j]&0xf) * multiplier; + multiplier *= 10; + j--; + } + + return n; +} \ No newline at end of file diff --git a/test b/test index 8b5eec8..0f46b94 100755 --- a/test +++ b/test @@ -10,4 +10,7 @@ echo "Day 1 with test data part 1 $(test_case 1 1 "test" "142"), and part 2 $(te echo "Day 1 with my data part 1 $(test_case 1 1 "my" "55621"), and part 2 $(test_case 1 2 "my" "53592")."; echo "Day 2 with test data part 1 $(test_case 2 1 "test" "8"), and part 2 $(test_case 2 2 "test" "2286")."; -echo "Day 2 with my data part 1 $(test_case 2 1 "my" "2727"), and part 2 $(test_case 2 2 "my" "56580")."; \ No newline at end of file +echo "Day 2 with my data part 1 $(test_case 2 1 "my" "2727"), and part 2 $(test_case 2 2 "my" "56580")."; + +echo "Day 3 with test data part 1 $(test_case 3 1 "test" "4361"), and part 2 $(test_case 3 2 "test" "467835")."; +echo "Day 3 with my data part 1 $(test_case 3 1 "my" "550934"), and part 2 $(test_case 3 2 "my" "81997870")."; \ No newline at end of file