Day 8
This commit is contained in:
parent
8fb9a3c795
commit
bb7144f964
1 changed files with 128 additions and 0 deletions
128
d08/main.odin
Normal file
128
d08/main.odin
Normal file
|
|
@ -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))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue