package main import "core:bytes" import "core:fmt" import "core:math" import "core:os" import "core:strconv" import "core:strings" Race :: struct { time: int, distance: int, } Input :: struct { races: [dynamic]Race, } Result1 :: distinct int Result2 :: distinct int // --- Input --- // print_input :: proc(input: ^Input) { fmt.printf("%#v\n", 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") } buf: bytes.Buffer bytes.buffer_init(&buf, raw_data) defer bytes.buffer_destroy(&buf) input.races = make([dynamic]Race, 0, 10) times, distances: []int { line, _ := bytes.buffer_read_string(&buf, '\n') line = line[:len(line) - 1] line_parts := strings.split(line, ":") defer delete(line_parts) numbers := strings.fields(line_parts[1]) times = make([]int, len(numbers)) for n, i in numbers { times[i] = strconv.atoi(n) } } defer delete(times) { line, _ := bytes.buffer_read_string(&buf, '\n') line = line[:len(line) - 1] line_parts := strings.split(line, ":") defer delete(line_parts) numbers := strings.fields(line_parts[1]) distances = make([]int, len(numbers)) for n, i in numbers { distances[i] = strconv.atoi(n) } } defer delete(distances) for i in 0 ..< len(times) { append(&input.races, Race{time = times[i], distance = distances[i]}) } return input } free_input :: proc(input: ^Input) { delete(input.races) } // --- Input --- // // --- Task 1 --- // run_task1 :: proc(input: ^Input, debug: bool) -> Result1 { result: Result1 = 1 if debug { print_input(input) } for race in input.races { min, max: f32 s := math.sqrt(f32((race.time * race.time) - (4 * -1 * -race.distance))) min = (f32(-race.time) + s) / -2 max = (f32(-race.time) - s) / -2 min = math.ceil(min + 1) if math.ceil(min) == min else math.ceil(min) max = math.floor(max - 1) if math.floor(max) == max else math.floor(max) result *= Result1(max - min + 1) } return result } print_result1 :: proc(result: ^Result1) { fmt.printf("Task 1: %d\n", result^) } // --- Task 1 --- // // --- Task 2 --- // run_task2 :: proc(input: ^Input, debug: bool) -> Result2 { if debug { print_input(input) } time, distance: int for race in input.races { if race.time < 10 { time *= 10 } else if race.time < 100 { time *= 100 } else if race.time < 1000 { time *= 1000 } else if race.time < 10000 { time *= 10000 } time += race.time if race.distance < 10 { distance *= 10 } else if race.distance < 100 { distance *= 100 } else if race.distance < 1000 { distance *= 1000 } else if race.distance < 10000 { distance *= 10000 } distance += race.distance } fmt.printf("%d %d\n", time, distance) min, max: f64 s := math.sqrt(f64((time * time) - (4 * -1 * -distance))) min = (f64(-time) + s) / -2 max = (f64(-time) - s) / -2 min = math.ceil(min + 1) if math.ceil(min) == min else math.ceil(min) max = math.floor(max - 1) if math.floor(max) == max else math.floor(max) return Result2(max - min + 1) } print_result2 :: proc(result: ^Result2) { fmt.printf("Task 2: %d\n", result^) } // --- Task 2 --- //