diff --git a/d05/main.odin b/d05/main.odin new file mode 100644 index 0000000..00db4e6 --- /dev/null +++ b/d05/main.odin @@ -0,0 +1,103 @@ +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" + +Range :: struct { + low: int, + high: int, +} + +in_range_inclusive :: proc(a, l, h: $T) -> bool { + return a >= l && a <= h +} + +part_1 :: proc(lines: []string) { + result := 0 + split_idx, _ := slice.linear_search(lines, "") + ranges, ids := slice.split_at(lines, split_idx) + + fresh_ranges, _ := slice.mapper(ranges, proc(range: string) -> Range { + parts := strings.split(range, "-") + low, _ := strconv.parse_int(parts[0]) + high, _ := strconv.parse_int(parts[1]) + + return Range{low = low, high = high} + }) + ing_ids, _ := slice.mapper(ids, proc(id: string) -> int { + ing_id, _ := strconv.parse_int(id) + return ing_id + }) + context.user_ptr = &fresh_ranges + fresh_ids := slice.filter(ing_ids, proc(id: int) -> bool { + fresh_ranges := (^[]Range)(context.user_ptr) + for r in fresh_ranges { + if in_range_inclusive(id, r.low, r.high) do return true + } + return false + }) + result = len(fresh_ids) + + fmt.printfln(" [Result] %v", result) +} + +part_2 :: proc(lines: []string) { + result := 0 + split_idx, _ := slice.linear_search(lines, "") + ranges, _ := slice.split_at(lines, split_idx) + + fresh_ranges, _ := slice.mapper(ranges, proc(range: string) -> Range { + parts := strings.split(range, "-") + low, _ := strconv.parse_int(parts[0]) + high, _ := strconv.parse_int(parts[1]) + return Range{low = low, high = high} + }) + slice.sort_by(fresh_ranges, proc(a, b: Range) -> bool { + return a.low < b.low + }) + + current := fresh_ranges[0] + for i in 1 ..< len(fresh_ranges) { + r := fresh_ranges[i] + if r.low <= current.high + 1 { + current.high = max(current.high, r.high) + } else { + result += current.high - current.low + 1 + current = r + } + } + result += current.high - current.low + 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)) +}