165 lines
4.3 KiB
Plaintext
165 lines
4.3 KiB
Plaintext
sample :: #string END
|
|
123 328 51 64
|
|
45 64 387 23
|
|
6 98 215 314
|
|
* + * +
|
|
END
|
|
|
|
Operation_Kind :: enum {
|
|
Plus;
|
|
Mult;
|
|
}
|
|
|
|
Operation :: struct {
|
|
values: [..]int;
|
|
op: Operation_Kind;
|
|
}
|
|
|
|
main :: () {
|
|
content := read_entire_file("day6.input");
|
|
// solve_first(content);
|
|
solve_second(content);
|
|
}
|
|
|
|
solve_second :: (input: string) {
|
|
lines := split(input, "\n");
|
|
num_values_per_operation := lines.count - 1;
|
|
in_progress_values: [..]string;
|
|
operations: [..]Operation;
|
|
for < char_index: 0..lines[0].count - 1 {
|
|
sb: String_Builder;
|
|
for line_index: 0..lines.count - 1 {
|
|
if lines[line_index].count == 0 continue;
|
|
c := lines[line_index][char_index];
|
|
if c == {
|
|
case #char " "; continue;
|
|
case #char "+"; {
|
|
op: Operation;
|
|
for s: in_progress_values {
|
|
value, success := parse_int(*s);
|
|
if success {
|
|
array_add(*op.values, value);
|
|
}
|
|
}
|
|
|
|
s := builder_to_string(*sb);
|
|
value, success := parse_int(*s);
|
|
if success {
|
|
array_add(*op.values, value);
|
|
}
|
|
|
|
array_reset_keeping_memory(*in_progress_values);
|
|
op.op = .Plus;
|
|
array_add(*operations, op);
|
|
}
|
|
case #char "*"; {
|
|
op: Operation;
|
|
for s: in_progress_values {
|
|
parse_me := s;
|
|
value, success := parse_int(*parse_me);
|
|
if success {
|
|
array_add(*op.values, value);
|
|
}
|
|
}
|
|
|
|
s := builder_to_string(*sb);
|
|
value, success := parse_int(*s);
|
|
if success {
|
|
array_add(*op.values, value);
|
|
}
|
|
|
|
array_reset_keeping_memory(*in_progress_values);
|
|
op.op = .Mult;
|
|
array_add(*operations, op);
|
|
}
|
|
case; {
|
|
append(*sb, c);
|
|
}
|
|
}
|
|
}
|
|
if builder_string_length(*sb) != 0 {
|
|
array_add(*in_progress_values, builder_to_string(*sb));
|
|
}
|
|
}
|
|
|
|
total := 0;
|
|
for operations total += evaluate(it);
|
|
|
|
print("%\n", total);
|
|
}
|
|
|
|
solve_first :: (input: string) {
|
|
operations := parse_input(input);
|
|
total := 0;
|
|
for operations {
|
|
total += evaluate(it);
|
|
}
|
|
|
|
print("%\n", total);
|
|
}
|
|
|
|
evaluate :: (operation: Operation) -> int {
|
|
result := 0;
|
|
if operation.op == .Plus {
|
|
for operation.values {
|
|
result += it;
|
|
}
|
|
} else {
|
|
result = 1;
|
|
for operation.values {
|
|
result *= it;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
parse_input :: (input: string) -> [..]Operation {
|
|
result: [..]Operation;
|
|
lines := split(input, #char "\n");
|
|
assert(lines.count > 0);
|
|
|
|
for line, line_index: lines {
|
|
found := true;
|
|
right := line;
|
|
op_index := 0;
|
|
while found {
|
|
defer op_index += 1;
|
|
found, left:, right = split_from_left(right, #char " ");
|
|
while left.count == 0 && found {
|
|
found, left, right = split_from_left(right, #char " ");
|
|
}
|
|
|
|
if found || left.count != 0 {
|
|
l := left;
|
|
val, success := parse_int(*l);
|
|
if !success {
|
|
if left == {
|
|
case "*"; result[op_index].op = .Mult;
|
|
case "+"; result[op_index].op = .Plus;
|
|
}
|
|
} else {
|
|
if line_index == 0 {
|
|
values: [..]int;
|
|
array_add(*values, val);
|
|
array_add(*result, .{values=values});
|
|
} else {
|
|
array_add(*result[op_index].values, val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
to_string :: (c: *u8) -> string {
|
|
return .{data=c, count=1};
|
|
}
|
|
|
|
#import "Basic";
|
|
#import "File";
|
|
#import "Print_Vars";
|
|
#import "String";
|