const std = @import("std"); const Operation = enum { multiplication, addition, }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); var stdin_buffer: [4096]u8 = undefined; var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer); const stdin = &stdin_reader.interface; const allocator = gpa.allocator(); var operands = try std.ArrayList(std.ArrayList(u64)).initCapacity(allocator, 1); defer operands.deinit(allocator); var charmap = try std.ArrayList(std.ArrayList(u8)).initCapacity(allocator, 1); defer charmap.deinit(allocator); var operations = try std.ArrayList(Operation).initCapacity(allocator, 1); defer operations.deinit(allocator); var operand_num: u64 = 0; while (try stdin.takeDelimiter('\n')) |line| { var it = std.mem.splitScalar(u8, line, ' '); if (line[0] != '*' and line[0] != '+') { var charrow = try std.ArrayList(u8).initCapacity(allocator, 1); for (line) |char| { try charrow.append(allocator, char); } try charmap.append(allocator, charrow); var i: usize = 0; while (it.next()) |part| { const part_trimmed = std.mem.trim(u8, part, " "); if (part_trimmed.len == 0) { continue; } const num = try std.fmt.parseInt(u64, part_trimmed, 10); if (operand_num == 0) { const operand_list = try std.ArrayList(u64).initCapacity(allocator, 1); try operands.append(allocator, operand_list); } try operands.items[i].append(allocator, num); i += 1; } operand_num += 1; } else { while (it.next()) |part| { const part_trimmed = std.mem.trim(u8, part, " "); if (part_trimmed.len == 0) { continue; } const operation = switch (part_trimmed[0]) { '*' => Operation.multiplication, '+' => Operation.addition, else => unreachable, }; try operations.append(allocator, operation); } } } var task1: u64 = 0; for (operands.items, 0..) |operand_list, i| { const operation = operations.items[i]; // Task1 var result: u64 = if (operation == Operation.multiplication) 1 else 0; for (operand_list.items) |operand| { switch (operation) { Operation.addition => { result += operand; }, Operation.multiplication => { result *= operand; }, } } task1 += result; } var charcolumns = try std.ArrayList(std.ArrayList(u8)).initCapacity(allocator, 1); defer charcolumns.deinit(allocator); for (0..charmap.items[0].items.len) |_| { const charcolumn = try std.ArrayList(u8).initCapacity(allocator, 1); try charcolumns.append(allocator, charcolumn); } for (charmap.items) |charrow| { for (charrow.items, 0..) |char, j| { try charcolumns.items[j].append(allocator, char); } } var task2: u64 = 0; var operation_count: u32 = 0; var current_operation = operations.items[0]; var result: u64 = if (current_operation == Operation.multiplication) 1 else 0; // Task2 for (charcolumns.items, 0..) |charcolumn, i| { var empty = true; for (charcolumn.items) |char| { if (char != ' ') { empty = false; break; } } if (!empty) { const num = try std.fmt.parseInt(u64, std.mem.trim(u8, charcolumn.items, " "), 10); switch (current_operation) { Operation.addition => { result += num; }, Operation.multiplication => { result *= num; }, } if (i != charcolumns.items.len - 1) { continue; } } task2 += result; operation_count += 1; if (operation_count < operations.items.len) { current_operation = operations.items[operation_count]; result = if (current_operation == Operation.multiplication) 1 else 0; } } for (operands.items) |*operand_list| { operand_list.deinit(allocator); } for (charcolumns.items) |*charcolumn| { charcolumn.deinit(allocator); } for (charmap.items) |*charrow| { charrow.deinit(allocator); } std.debug.print("{d}\n", .{task1}); std.debug.print("{d}\n", .{task2}); }