aoc20/d08/main.odin
2025-10-05 18:09:11 +02:00

114 lines
3 KiB
Odin

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)
}