package day_05
import "core:log"
import "core:os"
import "core:strconv"
import "core:strings"
Input :: struct {
fresh_ranges: [][2]int,
ingredients: []int,
}
Result1 :: int
Result2 :: int
// --- Input --- //
print_input :: proc(input: Input) {
log.infof("%#v", input)
}
parse_input_file :: proc(filepath: string) -> Input {
input: Input
raw_data, ok := os.read_entire_file_from_filename(filepath)
if !ok {
panic("oh no, could not read file")
}
defer delete(raw_data)
lines, err := strings.split_lines(strings.trim_right_space(string(raw_data)))
if err != .None {
panic("oh no, failed splitting into lines")
}
defer delete(lines)
split := 0
for line, i in lines {
if line == "" {
split = i
break
}
}
input.fresh_ranges = make([][2]int, split)
input.ingredients = make([]int, len(lines) - split - 1)
for line, i in lines[:split] {
range := strings.split(line, "-")
defer delete(range)
a := strconv.parse_int(range[0]) or_else 0
b := strconv.parse_int(range[1]) or_else 0
input.fresh_ranges[i] = {a, b}
}
for line, i in lines[split + 1:] {
input.ingredients[i] = strconv.parse_int(line) or_else 0
}
log.debugf("%d %d", len(input.ingredients), len(input.fresh_ranges))
log.debugf("%#v", input)
return input
}
free_input :: proc(input: ^Input) {
delete(input.fresh_ranges)
delete(input.ingredients)
}
// --- Input --- //
// --- Helpers --- //
// --- Helpers --- //
// --- Task 1 --- //
run_task1 :: proc(input: Input) -> Result1 {
result: Result1
for i in input.ingredients {
for fr in input.fresh_ranges {
if i >= fr[0] && i <= fr[1] {
result += 1
break
}
}
}
return result
}
print_result1 :: proc(result: Result1) {
log.infof("Task 1: %d", result)
}
// --- Task 1 --- //
// --- Task 2 --- //
run_task2 :: proc(input: Input) -> Result2 {
result: Result2
ranges := input.fresh_ranges
current_ranges := make([][2]int, len(ranges))
defer delete(current_ranges)
expanded := true
for expanded {
expanded = false
for i := 0; i < len(ranges); i += 1 {
current := ranges[i]
if current == {0, 0} {
continue
}
for j := i + 1; j < len(ranges); j += 1 {
range := ranges[j]
if range == {0, 0} {
continue
}
if current[0] <= range[1] && range[0] <= current[1] {
current[0] = min(current[0], range[0])
current[1] = max(current[1], range[1])
expanded = true
ranges[j] = {0, 0}
}
}
current_ranges[i] = current
}
ranges = current_ranges
log.debugf("%v -> %v", ranges, current_ranges)
}
log.debugf("final ranges %#v", ranges)
for r in ranges {
if r == {0, 0} {
continue
}
result += (r[1] - r[0]) + 1
}
return result
}
print_result2 :: proc(result: Result2) {
log.infof("Task 2: %d", result)
}
// --- Task 2 --- //
run :: proc() {
input := parse_input_file("input/day_05.txt")
defer free_input(&input)
result1 := run_task1(input)
print_result1(result1)
result2 := run_task2(input)
print_result2(result2)
}