part1.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <assert.h>
  6. #include "vec.h"
  7. #include "str.h"
  8. void* read_input() {
  9. FILE* fp = fopen("./input", "r");
  10. void *vec = new_vec();
  11. while(1) {
  12. char *line = fgetline(fp);
  13. if (line == NULL) break;
  14. char *stripped = str_strip(line);
  15. if (strlen(stripped) == 0) break;
  16. vec_push_back(vec, stripped);
  17. }
  18. return vec;
  19. }
  20. typedef struct {
  21. int line;
  22. int column;
  23. int value;
  24. int length;
  25. } num_t;
  26. void *parse_nums(void *schema) {
  27. void *nums = new_vec();
  28. int j = 0;
  29. const int IN_NUM = 0, IDLE = 1;
  30. int state = IDLE;
  31. for (int i = 0; i < vec_size(schema); i++) {
  32. char *line = vec_get(schema, i);
  33. int line_len = strlen(line);
  34. int value = 0;
  35. int length = 0;
  36. state = IDLE;
  37. j = 0;
  38. while (1) {
  39. char c = '.';
  40. if (j < line_len) c = line[j];
  41. if (state == IDLE) {
  42. if (isdigit(c)) {
  43. state = IN_NUM;
  44. continue;
  45. } else {
  46. j++;
  47. if (j >= line_len) break;
  48. continue;
  49. }
  50. } else if (state == IN_NUM) {
  51. if (isdigit(c)) {
  52. value = value * 10 + (c - '0');
  53. length++;
  54. j++;
  55. continue;
  56. } else {
  57. num_t *n = malloc(sizeof(num_t));
  58. *n = (num_t){
  59. .line = i,
  60. .column = j - length,
  61. .value = value,
  62. .length = length
  63. };
  64. vec_push_back(nums, n);
  65. value = 0;
  66. length = 0;
  67. state = IDLE;
  68. if (j >= line_len) break;
  69. continue;
  70. }
  71. }
  72. }
  73. }
  74. return nums;
  75. }
  76. int is_symbol(char c) {
  77. if (c >= '0' && c <= '9') return 0;
  78. if (c == '.') return 0;
  79. return 1;
  80. }
  81. int is_a_part(void *schema, num_t *num) {
  82. int line_len = vec_size(schema);
  83. int col_len = strlen(vec_get(schema, 0));
  84. for (int i = num->column - 1; i < num->column + num->length + 1; i++) {
  85. if (num->line - 1 < 0) continue;
  86. if (i < 0 || i >= col_len) continue;
  87. if (is_symbol(((char*)vec_get(schema, num->line - 1))[i])) {
  88. return 1;
  89. }
  90. }
  91. for (int i = num->column - 1; i < num->column + num->length + 1; i++) {
  92. if (num->line + 1 >= line_len) continue;
  93. if (i < 0 || i >= col_len) continue;
  94. if (is_symbol(((char*)vec_get(schema, num->line + 1))[i])) {
  95. return 1;
  96. }
  97. }
  98. if (num->column - 1 >= 0) {
  99. if (is_symbol(((char*)vec_get(schema, num->line))[num->column - 1])) {
  100. return 1;
  101. }
  102. }
  103. if (num->column + num->length < col_len) {
  104. char *line = vec_get(schema, num->line);
  105. if (is_symbol(line[num->column + num->length])) {
  106. return 1;
  107. }
  108. }
  109. return 0;
  110. }
  111. int main() {
  112. void *schema = read_input();
  113. void *nums = parse_nums(schema);
  114. int sum = 0;
  115. for (int i = 0; i < vec_size(nums); i++) {
  116. num_t *num = vec_get(nums, i);
  117. if (is_a_part(schema, num)) {
  118. sum += num->value;
  119. }
  120. }
  121. printf("%d\n", sum);
  122. return 0;
  123. }