diff --git a/d08/main.odin b/d08/main.odin new file mode 100644 index 0000000..c2606a9 --- /dev/null +++ b/d08/main.odin @@ -0,0 +1,114 @@ +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) +}