Ryan is an engineer in the Sacramento Area with a focus in Python, Ruby, and Rust. Bash/Python Exercism mentor. Coding, physics, calculus, music, woodworking. Looking for work!
Had a much better time today. I'm very happy with how this came out.
#include "Day8.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "parsing.h"
/// Day 8: Handheld Halting/// /// Figure out how to break a handheld game out of an infinite loop!/// The type of operation that is usedtypedefenum{OP_NOP,///< No operationOP_ACC,///< Adjust acc by argOP_JMP,///< Jump to arg location, relative to current ip}Opcode;/// A full instruction line in the programtypedefstruct{Opcodeop;///< The operation to be doneintarg;///< A positive or negative integer argument}Instruction;/// A program that keeps track of whether it has already run codetypedefstruct{Instruction*program;///< List of instructions to be runintip;///< Index of the current instruction to runintacc;///< Acc value adjusted by the acc opcodeintlines;///< Number of lines in the programbool*line_run;///< List of booleans denoting whether each line has run yet}Interpreter;/// Check if the current line has already been run#define HAS_ALREADY_RUN(interp) (interp.line_run[interp.ip])
/// Label this line as already run#define MARK_AS_RUN(interp) (interp.line_run[interp.ip] = true)
/// Create a new interpreter from an input filestaticInterpreternew_interpreter(constchar*filename){FILE*fp;fp=fopen(filename,"r");if(fp==NULL){printf("Couldn't open input file.\n");exit(EXIT_FAILURE);}Interpreterinterpreter;intlines=count_lines(fp);Instruction*program=(Instruction*)malloc(sizeof(Instruction)*lines);for(inti=0;i<lines;i++){charop[4]={0};intarg=0;fscanf(fp,"%s %d\n",op,&arg);Instructioninstruction={0};switch(op[0]){case'n':instruction.op=OP_NOP;break;case'a':instruction.op=OP_ACC;break;case'j':instruction.op=OP_JMP;break;default:printf("Unrecognized opcode %s.\n",op);exit(EXIT_FAILURE);}instruction.arg=arg;program[i]=instruction;}fclose(fp);interpreter.ip=0;interpreter.acc=0;interpreter.lines=lines;interpreter.line_run=(bool*)malloc(sizeof(bool)*lines);memset(interpreter.line_run,0,sizeof(bool)*lines);interpreter.program=program;returninterpreter;}/// Free an interpreter's malloced memoryvoidfree_interpreter(Interpreter*interpreter){free(interpreter->program);interpreter->program=NULL;free(interpreter->line_run);interpreter->line_run=NULL;}/// Run the instruction under the IPvoidtick(Interpreter*interpreter){Instructioninstruction=interpreter->program[interpreter->ip];switch(instruction.op){caseOP_NOP:interpreter->ip++;break;caseOP_ACC:interpreter->acc+=instruction.arg;interpreter->ip++;break;caseOP_JMP:interpreter->ip+=instruction.arg;break;}}/// What is the value of the acc when the first loop is encountered?intpart1(constchar*filename){Interpreterinterpreter=new_interpreter(filename);while(true){if(HAS_ALREADY_RUN(interpreter)){returninterpreter.acc;}else{MARK_AS_RUN(interpreter);}tick(&interpreter);}}/// Makes a standalone copy of an interpreterInterpretercopy_interpreter(Interpreter*orig){Interpreternew;new.ip=orig->ip;new.acc=orig->acc;new.lines=orig->lines;new.line_run=(bool*)malloc(sizeof(bool)*new.lines);memcpy(new.line_run,orig->line_run,sizeof(bool)*new.lines);new.program=(Instruction*)malloc(sizeof(Instruction)*new.lines);memcpy(new.program,orig->program,sizeof(Instruction)*new.lines);returnnew;}/// If you change one of the JMP to a NOP or vice versa, the program/// will exit normally. When it actually does that, what is the/// value in acc?intpart2(constchar*filename){Interpreterbase=new_interpreter(filename);for(inti=0;i<base.lines;i++){if(base.program[i].op==OP_ACC)continue;Interpreterinterpreter=copy_interpreter(&base);if(interpreter.program[i].op==OP_JMP){interpreter.program[i].op=OP_NOP;}else{interpreter.program[i].op=OP_JMP;}while(true){if(HAS_ALREADY_RUN(interpreter)){break;}elseif(interpreter.ip>=interpreter.lines){returninterpreter.acc;}else{MARK_AS_RUN(interpreter);}tick(&interpreter);}free_interpreter(&interpreter);}return-1;}/// Run both days.intday8(){printf("====== Day 8 ======\n");printf("Part 1: %d\n",part1("data/day8.txt"));printf("Part 2: %d\n",part2("data/day8.txt"));returnEXIT_SUCCESS;}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Had a much better time today. I'm very happy with how this came out.