123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- 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);
- }
|