day8.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. int arraySize = 0;
  6. struct instruction {
  7. char name[4];
  8. int value;
  9. };
  10. void zeroArray(int *array) {
  11. for (int i = 0; i < arraySize; i++)
  12. array[i] = 0;
  13. }
  14. struct instruction **readInput(char *path) {
  15. struct instruction **instructions = NULL;
  16. FILE *fp = fopen(path, "r");
  17. if (!fp) {
  18. puts("Can't read");
  19. return NULL;
  20. }
  21. int index = 0;
  22. while (1) {
  23. struct instruction *p = malloc(sizeof(struct instruction));
  24. if (!p) return NULL;
  25. if (1 > fscanf(fp, "%s %d\n", p->name, &(p->value)))
  26. return NULL;
  27. arraySize++;
  28. struct instruction **newInstructions = realloc(instructions, sizeof(struct instruction*)*arraySize);
  29. if (!newInstructions) return NULL;
  30. instructions = newInstructions;
  31. instructions[index] = p;
  32. index++;
  33. if (feof(fp)) break;
  34. }
  35. fclose(fp);
  36. return instructions;
  37. }
  38. int processInstructions(struct instruction **instructions, int *executed) {
  39. int acc = 0;
  40. int index = 0;
  41. while(1) {
  42. if (index < 0 || index >= arraySize) break;
  43. if (executed[index]) break;
  44. struct instruction *currentInstruction = instructions[index];
  45. if (0 == (strcmp("nop", currentInstruction->name))) {
  46. executed[index] = 1;
  47. index++;
  48. continue;
  49. }
  50. if (0 == (strcmp("acc", currentInstruction->name))) {
  51. acc += currentInstruction->value;
  52. executed[index] = 1;
  53. index++;
  54. continue;
  55. }
  56. if (0 == (strcmp("jmp", currentInstruction->name))) {
  57. executed[index] = 1;
  58. index += currentInstruction->value;
  59. continue;
  60. }
  61. }
  62. return acc;
  63. }
  64. int checkArray(struct instruction **instructions, int *executed, int index) {
  65. int executedCheck[arraySize];
  66. zeroArray(executedCheck);
  67. while(1) {
  68. if (index < 0 || index >= arraySize) break;
  69. if (executed[index] || executedCheck[index]) break;
  70. struct instruction *currentInstruction = instructions[index];
  71. if (0 == (strcmp("nop", currentInstruction->name))) {
  72. executedCheck[index] = 1;
  73. index++;
  74. continue;
  75. }
  76. if (0 == (strcmp("acc", currentInstruction->name))) {
  77. executedCheck[index] = 1;
  78. index++;
  79. continue;
  80. }
  81. if (0 == (strcmp("jmp", currentInstruction->name))) {
  82. executedCheck[index] = 1;
  83. index += currentInstruction->value;
  84. continue;
  85. }
  86. }
  87. return index == arraySize;
  88. }
  89. int fixTheLoop(struct instruction **instructions, int *executed) {
  90. int acc = 0;
  91. int index = 0;
  92. int changed = 0;
  93. while(1) {
  94. if (index < 0 || index >= arraySize) break;
  95. if (executed[index]) break;
  96. struct instruction *currentInstruction = instructions[index];
  97. if (0 == (strcmp("nop", currentInstruction->name))) {
  98. executed[index] = 1;
  99. if (!changed && checkArray(instructions, executed, index+currentInstruction->value)) {
  100. changed = 1;
  101. index += currentInstruction->value;
  102. }
  103. else index++;
  104. continue;
  105. }
  106. if (0 == (strcmp("acc", currentInstruction->name))) {
  107. acc += currentInstruction->value;
  108. executed[index] = 1;
  109. index++;
  110. continue;
  111. }
  112. if (0 == (strcmp("jmp", currentInstruction->name))) {
  113. executed[index] = 1;
  114. if (!changed && checkArray(instructions, executed, index+1)) {
  115. changed = 1;
  116. index++;
  117. }
  118. else index += currentInstruction->value;
  119. continue;
  120. }
  121. }
  122. if (changed) return acc;
  123. return 1000000000;
  124. }
  125. void freeInstructions(struct instruction **instructions) {
  126. for (int i = 0; i < arraySize; i++)
  127. free(instructions[i]);
  128. free(instructions);
  129. }
  130. int main(int argc, char **argv)
  131. {
  132. if (argc < 2) {
  133. puts("You need to specify path to file!");
  134. return -1;
  135. }
  136. struct instruction **instructions = readInput(argv[1]);
  137. if (!instructions) {
  138. puts("Can't read array!");
  139. return -1;
  140. }
  141. int executed[arraySize];
  142. zeroArray(executed);
  143. printf("Part1: %d\n", processInstructions(instructions, executed));
  144. zeroArray(executed);
  145. printf("Part2: %d\n", fixTheLoop(instructions, executed));
  146. freeInstructions(instructions);
  147. }