package day6 import "core:log" import math "core:math" import "core:strconv" import "core:strings" import "core:testing" import "../utils" sample :: `123 328 51 64 45 64 387 23 6 98 215 314 * + * + ` Operation :: struct($N: uint) { values: [N]i64, operation: rune, } new_op :: proc($N: uint) -> Operation(N) { return {values = {-1, -1, -1}} } evaluate_op :: proc(op: Operation($N)) -> u64 { total: u64 for n in op.values { if n == -1 || n == 0 do continue if op.operation == '+' { total += u64(n) } else { if total == 0 do total += 1 total *= u64(n) } } return total } parse_operations :: proc(s: string, $N: uint) -> [dynamic]Operation(N) { ops: [dynamic]Operation(N) num_elements := 0 counter := s for line in strings.split_lines_iterator(&counter) { line := line for x in strings.split_iterator(&line, " ") { (x != "") or_continue num_elements += 1 } break } resize(&ops, num_elements) row := 0 buf := s for line in strings.split_lines_iterator(&buf) { (line != "") or_continue line := line col := 0 for x in strings.split_iterator(&line, " ") { (x != "") or_continue val, ok := strconv.parse_i64(x) if ok { ops[col].values[row] = val } else { ops[col].operation = rune(x[0]) } col += 1 } row += 1 } return ops } solve_first :: proc(s: string, $N: uint) -> u64 { ops := parse_operations(s, N) defer delete(ops) total: u64 = 0 for op in ops { total += evaluate_op(op) } return total } @(test) solve_first_sample :: proc(t: ^testing.T) { testing.expect_value(t, solve_first(sample, 3), 4277556) } @(test) solve_first_puzzle :: proc(t: ^testing.T) { content := utils.read_file("day6/input.txt") defer delete(content) testing.expect_value(t, solve_first(content, 4), 6209956042374) } solve_second :: proc(s: string, $N: uint) -> u64 { lines := strings.split_lines(s) defer delete(lines) assert(N == len(lines) - 1) ops: [dynamic]Operation(N) defer delete(ops) op: Operation(N) op_i := N - 1 for i in 0 ..< len(lines[0]) { val: i64 if lines[0][i] != ' ' { val += i64(lines[0][i] - '0') } for j in 1 ..< N { c := lines[j][i] if c != ' ' { val *= 10 val += i64(c - '0') } } if lines[N][i] != ' ' { op.operation = rune(lines[N][i]) } if val == 0 { append(&ops, op) op = {} op_i = N - 1 } else { op.values[op_i] = val op_i -= 1 } } append(&ops, op) total: u64 = 0 for op in ops { total += evaluate_op(op) } return total } @(test) solve_second_sample :: proc(t: ^testing.T) { testing.expect_value(t, solve_second(sample, 3), 3263827) } @(test) solve_second_puzzle :: proc(t: ^testing.T) { content := utils.read_file("day6/input.txt") defer delete(content) testing.expect_value(t, solve_second(content, 4), 12608160008022) }