#define _GNU_SOURCE #include #include #include int arraySize = 0; struct instruction { char name[4]; int value; }; void zeroArray(int *array) { for (int i = 0; i < arraySize; i++) array[i] = 0; } struct instruction **readInput(char *path) { struct instruction **instructions = NULL; FILE *fp = fopen(path, "r"); if (!fp) { puts("Can't read"); return NULL; } int index = 0; while (1) { struct instruction *p = malloc(sizeof(struct instruction)); if (!p) return NULL; if (1 > fscanf(fp, "%s %d\n", p->name, &(p->value))) return NULL; arraySize++; struct instruction **newInstructions = realloc(instructions, sizeof(struct instruction*)*arraySize); if (!newInstructions) return NULL; instructions = newInstructions; instructions[index] = p; index++; if (feof(fp)) break; } fclose(fp); return instructions; } int processInstructions(struct instruction **instructions, int *executed) { int acc = 0; int index = 0; while(1) { if (index < 0 || index >= arraySize) break; if (executed[index]) break; struct instruction *currentInstruction = instructions[index]; if (0 == (strcmp("nop", currentInstruction->name))) { executed[index] = 1; index++; continue; } if (0 == (strcmp("acc", currentInstruction->name))) { acc += currentInstruction->value; executed[index] = 1; index++; continue; } if (0 == (strcmp("jmp", currentInstruction->name))) { executed[index] = 1; index += currentInstruction->value; continue; } } return acc; } int checkArray(struct instruction **instructions, int *executed, int index) { int executedCheck[arraySize]; zeroArray(executedCheck); while(1) { if (index < 0 || index >= arraySize) break; if (executed[index] || executedCheck[index]) break; struct instruction *currentInstruction = instructions[index]; if (0 == (strcmp("nop", currentInstruction->name))) { executedCheck[index] = 1; index++; continue; } if (0 == (strcmp("acc", currentInstruction->name))) { executedCheck[index] = 1; index++; continue; } if (0 == (strcmp("jmp", currentInstruction->name))) { executedCheck[index] = 1; index += currentInstruction->value; continue; } } return index == arraySize; } int fixTheLoop(struct instruction **instructions, int *executed) { int acc = 0; int index = 0; int changed = 0; while(1) { if (index < 0 || index >= arraySize) break; if (executed[index]) break; struct instruction *currentInstruction = instructions[index]; if (0 == (strcmp("nop", currentInstruction->name))) { executed[index] = 1; if (!changed && checkArray(instructions, executed, index+currentInstruction->value)) { changed = 1; index += currentInstruction->value; } else index++; continue; } if (0 == (strcmp("acc", currentInstruction->name))) { acc += currentInstruction->value; executed[index] = 1; index++; continue; } if (0 == (strcmp("jmp", currentInstruction->name))) { executed[index] = 1; if (!changed && checkArray(instructions, executed, index+1)) { changed = 1; index++; } else index += currentInstruction->value; continue; } } if (changed) return acc; return 1000000000; } void freeInstructions(struct instruction **instructions) { for (int i = 0; i < arraySize; i++) free(instructions[i]); free(instructions); } int main(int argc, char **argv) { if (argc < 2) { puts("You need to specify path to file!"); return -1; } struct instruction **instructions = readInput(argv[1]); if (!instructions) { puts("Can't read array!"); return -1; } int executed[arraySize]; zeroArray(executed); printf("Part1: %d\n", processInstructions(instructions, executed)); zeroArray(executed); printf("Part2: %d\n", fixTheLoop(instructions, executed)); freeInstructions(instructions); }