finish day 3
This commit is contained in:
155
day5/day5.odin
Normal file
155
day5/day5.odin
Normal file
@@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
import "core:strconv"
|
||||
import "core:testing"
|
||||
|
||||
sample :: `3-5
|
||||
10-14
|
||||
16-20
|
||||
12-18
|
||||
|
||||
1
|
||||
5
|
||||
8
|
||||
11
|
||||
17
|
||||
32`
|
||||
|
||||
Range :: struct {
|
||||
start: u64,
|
||||
end: u64,
|
||||
}
|
||||
|
||||
parse_range :: proc(s: string) -> Range {
|
||||
range: Range
|
||||
delim_index := strings.index_rune(s, '-')
|
||||
range.start, _ = strconv.parse_u64(s[:delim_index])
|
||||
range.end, _ = strconv.parse_u64(s[delim_index + 1:])
|
||||
return range
|
||||
}
|
||||
|
||||
solve_first :: proc(input: string) -> u64 {
|
||||
input := input
|
||||
fresh_ingredient_ids: [dynamic]Range
|
||||
defer delete(fresh_ingredient_ids)
|
||||
available_ingredient_ids: [dynamic]u64
|
||||
defer delete(available_ingredient_ids)
|
||||
in_ranges := true
|
||||
for line in strings.split_lines_iterator(&input) {
|
||||
if line == "" {
|
||||
in_ranges = false
|
||||
}
|
||||
if in_ranges {
|
||||
range := parse_range(line)
|
||||
append(&fresh_ingredient_ids, range)
|
||||
} else {
|
||||
val, _ := strconv.parse_u64(line)
|
||||
append(&available_ingredient_ids, val)
|
||||
}
|
||||
}
|
||||
|
||||
total_fresh: u64
|
||||
for id in available_ingredient_ids {
|
||||
for range in fresh_ingredient_ids {
|
||||
if range.start <= id && id <= range.end {
|
||||
total_fresh += 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return total_fresh
|
||||
}
|
||||
|
||||
@(test)
|
||||
solves_sample :: proc(^testing.T) {
|
||||
total_fresh := solve_first(sample)
|
||||
log.info("sample total fresh: %v", total_fresh)
|
||||
assert(total_fresh == 3)
|
||||
}
|
||||
|
||||
@(test)
|
||||
solves_input :: proc(^testing.T) {
|
||||
content, _ := os.read_entire_file("day5input.txt")
|
||||
defer delete(content)
|
||||
total_fresh := solve_first(string(content))
|
||||
log.info("input total fresh: %v", total_fresh)
|
||||
assert(total_fresh == 701)
|
||||
}
|
||||
|
||||
RangeResult :: struct {
|
||||
range: Range,
|
||||
primary: bool,
|
||||
used: bool
|
||||
}
|
||||
|
||||
solve_second :: proc(input: string) -> u64 {
|
||||
input := input
|
||||
fresh_set: [dynamic]RangeResult
|
||||
defer delete(fresh_set)
|
||||
for line in strings.split_lines_iterator(&input) {
|
||||
if line == "" {
|
||||
break
|
||||
}
|
||||
|
||||
range := parse_range(line)
|
||||
append(&fresh_set, RangeResult{ range=range })
|
||||
}
|
||||
|
||||
for &rr, index in fresh_set {
|
||||
r1 := rr
|
||||
if rr.used do continue
|
||||
rr.primary = true
|
||||
|
||||
if index == len(fresh_set) - 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
increased := true
|
||||
for increased {
|
||||
increased = false
|
||||
for &compare in fresh_set[index + 1:] {
|
||||
if compare.used do continue
|
||||
r := rr.range
|
||||
r2 := compare
|
||||
crr := compare.range
|
||||
if (crr.start <= r.start && r.start <= crr.end) ||
|
||||
(crr.start <= r.end && r.end <= crr.end) ||
|
||||
(crr.start <= r.start && r.end <= crr.end) ||
|
||||
(r.start <= crr.start && crr.end <= r.end) {
|
||||
rr.range.start = min(r.start, crr.start)
|
||||
rr.range.end = max(r.end, crr.end)
|
||||
compare.used = true
|
||||
increased = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total: u64
|
||||
for rr in fresh_set {
|
||||
if !rr.primary do continue
|
||||
total += (rr.range.end - rr.range.start) + 1
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
@(test)
|
||||
solves_second_sample :: proc(t: ^testing.T) {
|
||||
fresh_count := solve_second(sample)
|
||||
log.info("solves_second_sample count = %v", fresh_count)
|
||||
testing.expect_value(t, fresh_count, 14)
|
||||
}
|
||||
|
||||
@(test)
|
||||
solves_second_input :: proc(t: ^testing.T) {
|
||||
content, _ := os.read_entire_file("day5input.txt")
|
||||
defer delete(content)
|
||||
fresh_count := solve_second(string(content))
|
||||
log.info("solves_second_input count = %v", fresh_count)
|
||||
testing.expect_value(t, fresh_count, 352340558684863)
|
||||
}
|
||||
1186
day5/input.txt
Normal file
1186
day5/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user