From 3db1d783a5d01b6be444f8527f1d7f277b31a96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=A5rdbrink?= Date: Sun, 7 Dec 2025 01:14:21 +0100 Subject: [PATCH] Day 6 --- d06/main.odin | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 d06/main.odin diff --git a/d06/main.odin b/d06/main.odin new file mode 100644 index 0000000..f0cddf4 --- /dev/null +++ b/d06/main.odin @@ -0,0 +1,139 @@ +package main + +import "core:container/queue" +import "core:fmt" +import "core:math" +import "core:math/linalg" +import "core:os" +import "core:slice" +import "core:strconv" +import "core:strings" +import "core:time" +import "core:unicode/utf8" + +import util "../util" + +trim_and_filter :: proc(items: []string) -> []string { + result := make([dynamic]string) + for item in items { + trimmed := strings.trim_space(item) + if trimmed != "" do append(&result, trimmed) + } + return result[:] +} + +execute_operator :: proc(op: string, a, b: i64) -> i64 { + switch op { + case "+": + return a + b + case "*": + return a * b + } + panic("Invalid operator") +} + +part_1 :: proc(lines: []string) { + result: i64 = 0 + + operands_line := lines[len(lines) - 1] + operands_raw := strings.split(operands_line, " ") + operands := trim_and_filter(operands_raw) + + accs := make([]i64, len(operands)) + for op, idx in operands do if op == "*" do accs[idx] = 1 + + #reverse for line in lines[:len(lines) - 1] { + numbers_raw := strings.split(line, " ") + numbers := trim_and_filter(numbers_raw) + for number, idx in numbers { + num, _ := strconv.parse_i64(number) + accs[idx] = execute_operator(operands[idx], accs[idx], num) + } + } + result = math.sum(accs) + + fmt.printfln(" [Result] %v", result) +} + +part_2 :: proc(lines: []string) { + result: i64 = 0 + + operands_line := lines[len(lines) - 1] + operands_raw := strings.split(operands_line, " ") + operands := trim_and_filter(operands_raw) + + num_lines := lines[:len(lines) - 1] + + max_len := 0 + for line in num_lines { + if len(line) > max_len do max_len = len(line) + } + + transposed := make([dynamic]string) + for char_pos := 0; char_pos < max_len; char_pos += 1 { + sb := strings.builder_make() + for line in num_lines { + if char_pos < len(line) { + strings.write_byte(&sb, line[char_pos]) + } else { + strings.write_byte(&sb, ' ') + } + } + append(&transposed, strings.to_string(sb)) + strings.builder_destroy(&sb) + } + + groups := make([dynamic][dynamic]string) + current_group := make([dynamic]string) + + for vertical_str in transposed { + if strings.trim_space(vertical_str) == "" { + if len(current_group) > 0 { + append(&groups, current_group) + current_group = make([dynamic]string) + } + } else { + append(¤t_group, vertical_str) + } + } + if len(current_group) > 0 { + append(&groups, current_group) + } + + op_idx := 0 + for group in groups { + acc: i64 = 0 + if operands[op_idx] == "*" do acc = 1 + + for vertical_str in group { + num, _ := strconv.parse_i64(strings.trim_space(vertical_str)) + acc = execute_operator(operands[op_idx], acc, num) + } + + result += acc + op_idx += 1 + } + + fmt.printfln(" [Result] %v", 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] + + fmt.println("[Part 1]") + start := time.tick_now() + part_1(lines) + duration := time.tick_diff(start, time.tick_now()) + fmt.printfln(" [Time] %vms\n", time.duration_milliseconds(duration)) + + fmt.printfln("[Part 2]") + start = time.tick_now() + part_2(lines) + duration = time.tick_diff(start, time.tick_now()) + fmt.printfln(" [Time] %vms", time.duration_milliseconds(duration)) +}