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