package main import "core:math" import "core:slice" import "core:strconv" import "core:strings" import "core:bytes" import "core:fmt" import "core:os" import "../util" Instruction :: struct { type: string, value: i64, } Program :: struct { counter: i64, accumulator: i64, } part_1 :: proc(lines: []string) { result: i64 = 0 instructions := make([]Instruction, len(lines)) for line, idx in lines { parts := strings.split(line, " ") instruction := parts[0] value, ok := strconv.parse_i64(parts[1]); assert(ok) instructions[idx] = Instruction{ instruction, value } } program := Program{ counter = 0, accumulator = 0 } program_history := make([dynamic]i64) for program.counter < i64(len(instructions)) { if slice.contains(program_history[:], program.counter) { result = program.accumulator break } append(&program_history, program.counter) instruction := instructions[program.counter] switch instruction.type { case "acc": program.accumulator += instruction.value case "jmp": program.counter += instruction.value continue } program.counter += 1 } fmt.printfln("Part 1: %d", result) } part_2 :: proc(lines: []string) { result: i64 = 0 instructions := make([]Instruction, len(lines)) for line, idx in lines { parts := strings.split(line, " ") instruction := parts[0] value, ok := strconv.parse_i64(parts[1]); assert(ok) instructions[idx] = Instruction{ instruction, value } } outer_loop: for instruction, idx in instructions { test_instructions := slice.clone(instructions) switch instruction.type { case "nop": test_instructions[idx].type = "jmp" case "jmp": test_instructions[idx].type = "nop" } program := Program{ counter = 0, accumulator = 0 } program_history := make([dynamic]i64) for program.counter < i64(len(test_instructions)) { if slice.contains(program_history[:], program.counter) { result = program.accumulator continue outer_loop } append(&program_history, program.counter) test_instruction := test_instructions[program.counter] switch test_instruction.type { case "acc": program.accumulator += test_instruction.value case "jmp": program.counter += test_instruction.value continue } program.counter += 1 } result = program.accumulator break } fmt.printfln("Part 2: %d", result) } main :: proc() { context.allocator = context.temp_allocator defer free_all(context.temp_allocator) INPUT :: #load("input.txt", string) lines := strings.split(INPUT, "\n") lines = lines[:len(lines)-1] part_1(lines) part_2(lines) }