From bb7144f964272d5b6a00e4192cfc6ad808542ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=A5rdbrink?= Date: Mon, 8 Dec 2025 20:57:00 +0100 Subject: [PATCH] Day 8 --- d08/main.odin | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 d08/main.odin diff --git a/d08/main.odin b/d08/main.odin new file mode 100644 index 0000000..f10e7a5 --- /dev/null +++ b/d08/main.odin @@ -0,0 +1,128 @@ +package main + +import "base:intrinsics" +import "core:fmt" +import "core:math" +import "core:slice" +import "core:strconv" +import "core:strings" +import "core:time" + +Vec3 :: [3]int +Distance :: struct { + pos: Vec3, + distance: int, +} + +distance :: proc(a, b: Vec3) -> int { + dx := f32(b.x - a.x) + dy := f32(b.y - a.y) + dz := f32(b.z - a.z) + + return int(math.sqrt(dx * dx + dy * dy + dz * dz)) +} + +in_circuit :: proc(circuits: ^[dynamic][dynamic]Vec3, pos: Vec3) -> (circuit: ^[dynamic]Vec3, ok: bool) { + for &circuit in circuits { + if slice.contains(circuit[:], pos) do return &circuit, true + } + + return {}, false +} + +get_min_distance :: proc( + distance_table: ^[dynamic][dynamic]Distance, + position: []Vec3, +) -> ( + p1: Vec3, + p2: Vec3, + ok: bool, +) { + min := 10000000 + min_idx := 10000000 + for distances, idx in distance_table { + if len(distances) <= 0 do continue + if distances[0].distance < min { + min = distances[0].distance + min_idx = idx + p1 = position[idx] + p2 = distances[0].pos + ok = true + } + } + + if !ok do return + + pop(&distance_table[min_idx]) + return +} + +part_1 :: proc(lines: []string) { + result := 1 + positions := slice.mapper(lines, proc(line: string) -> Vec3 { + parts := strings.split(line, ",") + x, _ := strconv.parse_int(parts[0]) + y, _ := strconv.parse_int(parts[1]) + z, _ := strconv.parse_int(parts[2]) + return Vec3{x, y, z} + }) + + circuits := make([dynamic][dynamic]Vec3) + distance_table := make([dynamic][dynamic]Distance) + + for p1, idx1 in positions { + append(&distance_table, make([dynamic]Distance)) // Without itself + for p2, idx2 in positions { + if idx1 == idx2 do continue + append(&distance_table[idx1], Distance{p2, distance(p1, p2)}) + } + slice.sort_by(distance_table[idx1][:], proc(dst1, dst2: Distance) -> bool { + return dst1.distance < dst2.distance + }) + } + + for true { + p1, p2, found := get_min_distance(&distance_table, positions) + if !found do break + c, ok := in_circuit(&circuits, p1) + + if ok do append(c, p2) + else { + append(&circuits, make([dynamic]Vec3)) + new_c := &circuits[len(circuits) - 1] + append(new_c, p1) + append(new_c, p2) + } + } + for c in circuits do result *= fmt.println(len(c)) + for c in circuits do result *= len(c) + + fmt.printfln(" [Result] %v", result) +} + +part_2 :: proc(lines: []string) { + result: i64 = 0 + + 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)) +}