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)
}