package day_06 import "core:log" import "core:os" import "core:strconv" import "core:strings" Op :: enum (u8) { None, Add = '+', Mul = '*', } Column :: struct { op: Op, starts_at: int, ends_at: int, nums: []string, } Input :: struct { columns: []Column, } 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(string(raw_data)) if err != .None { panic("oh no, failed splitting into lines") } defer delete(lines) last := len(lines) - 2 num_nums := last num_columns: int for _, i in lines[last] { line := lines[last] if line[i] == u8(Op.Add) || line[i] == u8(Op.Mul) { num_columns += 1 } } input.columns = make([]Column, num_columns) for &c in input.columns { c.nums = make([]string, num_nums) } col: int for _, i in lines[last] { line := lines[last] if line[i] == u8(Op.Add) || line[i] == u8(Op.Mul) { input.columns[col].op = Op(line[i]) input.columns[col].starts_at = i if col > 0 { input.columns[col - 1].ends_at = i - 1 } col += 1 } input.columns[col - 1].ends_at = len(line) } for c in input.columns { for line, i in lines[:last] { c.nums[i] = strings.clone(line[c.starts_at:c.ends_at]) } } return input } free_input :: proc(input: ^Input) { for c in input.columns { for _, i in c.nums { delete(c.nums[i]) } delete(c.nums) } delete(input.columns) input.columns = nil } // --- Input --- // // --- Helpers --- // // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: Input) -> Result1 { result: Result1 for c in input.columns { val: int if c.op == .Add { for n in c.nums { val += strconv.parse_int(strings.trim_space(n)) or_else 0 } } else if c.op == .Mul { val = 1 for n in c.nums { val *= strconv.parse_int(strings.trim_space(n)) or_else 0 } } log.debugf("%v => %d", c, val) result += val } 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 for c_i in 0 ..< len(input.columns) { c := input.columns[len(input.columns) - 1 - c_i] r := c.ends_at - c.starts_at total := 1 if c.op == .Mul else 0 for i in 0 ..< r { val := 0 for num in c.nums { digit := num[r - 1 - i] if digit != ' ' { val = (val * 10) + int(digit - '0') } } if c.op == .Add { total += val } else if c.op == .Mul { total *= val } log.debugf("-> %d", val) } log.debugf("== %d", total) result += total } return result } print_result2 :: proc(result: Result2) { log.infof("Task 2: %d", result) } // --- Task 2 --- // run :: proc() { input := parse_input_file("input/day_06.txt") defer free_input(&input) result1 := run_task1(input) print_result1(result1) result2 := run_task2(input) print_result2(result2) }