#import "File";
#import "String";
#import "Basic";
#import "Math";
solve_day5 :: (test: bool) {
contents := read_entire_file("inputs/day5.txt");
sections := split(contents, "\n\n");
seeds_split := split(slice(sections[0], 7, sections[0].count - 7), " ");
seeds: [..]u64;
list_of_translations: [..][..]Seed_Translation;
for seeds_split {
array_add(*seeds, string_to_int(it, 10, u64));
}
for section: sections {
lines := split(section, "\n");
translation := array_add(*list_of_translations);
for line: array_view(lines, 1, lines.count - 1) {
if line.count == 0 continue;
seeds := split(line, " ");
source := string_to_int(seeds[1], 10, u64);
destination := string_to_int(seeds[0], 10, u64);
amount := string_to_int(seeds[2], 10, u64);
array_add(translation, .{
source = source,
destination = destination,
amount = amount,
});
}
}
smallest_val: u64 = U64_MAX;
for seed: seeds {
current_seed := seed;
for list_of_translations {
current_seed = convert_seed(current_seed, it);
}
smallest_val = min(smallest_val, current_seed);
}
print("Part 1: %\n", smallest_val);
part2: u64 = U64_MAX;
seed_ranges: [..]Seed_Range;
for i: 0..(seeds.count - 1) / 2 {
array_add(*seed_ranges, .{ from = seeds[i * 2], amount = seeds[i * 2 + 1] });
}
for seed_range: seed_ranges {
work: [..]Seed_Range;
array_add(*work, seed_range);
for translations: list_of_translations {
work = make_ranges(work, translations);
}
for item: work {
part2 = min(part2, item.from);
}
}
print("Part 2: %\n", part2);
}
make_ranges :: (seed_ranges: [..]Seed_Range, remap_ranges: [..]Seed_Translation) -> [..]Seed_Range {
list1 := array_copy(seed_ranges);
defer array_free(list1);
list2: [..]Seed_Range;
for remap_range: remap_ranges {
for i: 0..list1.count - 1 {
from := list1[i].from;
amount := list1[i].amount;
to := from + amount;
if from >= remap_range.source && from < (remap_range.source + remap_range.amount) &&
to > remap_range.source && to <= (remap_range.source + remap_range.amount) {
array_add(*list2, .{
from = from + remap_range.destination - remap_range.source,
amount = amount,
});
list1[i].amount = 0;
list1[i].from = U64_MAX;
} else if from >= remap_range.source && from < (remap_range.source + remap_range.amount) {
overlap := remap_range.source + remap_range.amount - from;
list1[i].amount = amount - overlap;
list1[i].from = from + overlap;
array_add(*list2, .{
from = remap_range.destination + (from - remap_range.source),
amount = overlap,
});
} else if to >= remap_range.source && to <= (remap_range.source + remap_range.amount) {
overlap := from + amount - remap_range.source;
list1[i].amount = amount - overlap;
array_add(*list2, .{
from = remap_range.destination,
amount = overlap,
});
}
}
}
for item: list1 {
if item.amount > 0 {
array_add(*list2, item);
}
}
return list2;
}
convert_seed :: (seed: u64, translations: [..]Seed_Translation) -> u64 {
result := seed;
for translation: translations {
if translation.source <= result && (translation.source + translation.amount) > result {
result = result + translation.destination - translation.source;
break;
}
}
return result;
}
Seed_Range :: struct {
from: u64;
amount: u64;
}
Seed_Translation :: struct {
source: u64;
destination: u64;
amount: u64;
}