mirror of
https://github.com/thegeneralist01/aoc
synced 2026-03-07 10:59:54 +01:00
142 lines
4.4 KiB
Zig
142 lines
4.4 KiB
Zig
const std = @import("std");
|
|
|
|
fn is_digit(c: u8) bool {
|
|
return switch (c) {
|
|
'0'...'9' => true,
|
|
else => false,
|
|
};
|
|
}
|
|
|
|
fn parse_mul(s: []const u8) !i32 {
|
|
if (s.len < 8) return -1;
|
|
if (s[0] != 'm') return -1;
|
|
if (s[1] != 'u') return -1;
|
|
if (s[2] != 'l') return -1;
|
|
if (s[3] != '(') return -1;
|
|
var int1: u32 = 0;
|
|
var int2: u32 = 0;
|
|
var comma_ind: usize = 0;
|
|
for (s[4..], 0..) |c, i| {
|
|
if (c == ',') {
|
|
comma_ind = 5 + i;
|
|
break;
|
|
} else if (!is_digit(c)) {
|
|
std.debug.print("{c}\n", .{c});
|
|
return -1;
|
|
}
|
|
int1 = int1 * 10 + try std.fmt.parseInt(u16, &[_]u8{c}, 10);
|
|
}
|
|
for (s[comma_ind..]) |c| {
|
|
if (c == ')') {
|
|
break;
|
|
}
|
|
int2 = int2 * 10 + try std.fmt.parseInt(u16, &[_]u8{c}, 10);
|
|
}
|
|
return @intCast(int1 * int2);
|
|
}
|
|
|
|
fn parse_do(s: []const u8) !i8 {
|
|
if (s.len == 4) {
|
|
// do()
|
|
if (s[0] != 'd') return 0;
|
|
if (s[1] != 'o') return 0;
|
|
if (s[2] != '(') return 0;
|
|
if (s[3] != ')') return 0;
|
|
return 1;
|
|
} else if (s.len == 7) {
|
|
// don't()
|
|
if (s[0] != 'd') return 0;
|
|
if (s[1] != 'o') return 0;
|
|
if (s[2] != 'n') return 0;
|
|
if (s[3] != '\'') return 0;
|
|
if (s[4] != 't') return 0;
|
|
if (s[5] != '(') return 0;
|
|
if (s[6] != ')') return 0;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
pub fn main() !void {
|
|
const file = try std.fs.cwd().openFile("input", .{});
|
|
defer file.close();
|
|
const file_reader = file.reader();
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const ally = gpa.allocator();
|
|
defer _ = gpa.deinit();
|
|
|
|
var input_buf = std.ArrayListUnmanaged(u8){};
|
|
defer input_buf.deinit(ally);
|
|
|
|
var match_mul_str = std.ArrayListUnmanaged(u8){};
|
|
try match_mul_str.ensureTotalCapacity(ally, 15);
|
|
defer match_mul_str.deinit(ally);
|
|
var matching_mul = false;
|
|
var matching_mul_ind: u32 = 0;
|
|
var mul_lock = false;
|
|
|
|
var match_do_str = std.ArrayListUnmanaged(u8){};
|
|
try match_do_str.ensureTotalCapacity(ally, 15);
|
|
defer match_do_str.deinit(ally);
|
|
var matching_do = false;
|
|
var matching_do_ind: u32 = 0;
|
|
|
|
var sum: u32 = 0;
|
|
while (true) {
|
|
defer input_buf.clearRetainingCapacity();
|
|
file_reader.streamUntilDelimiter(input_buf.writer(ally), '\n', null) catch |err| switch (err) {
|
|
error.EndOfStream => break,
|
|
else => break,
|
|
};
|
|
|
|
for (input_buf.items, 0..) |c, i| {
|
|
if (matching_mul and !mul_lock) {
|
|
if (c != 'm' and c != 'u' and c != 'l' and c != '(' and c != ')' and c != ',' and !is_digit(c)) {
|
|
matching_mul = false;
|
|
match_mul_str.clearRetainingCapacity();
|
|
continue;
|
|
}
|
|
|
|
try match_mul_str.append(ally, c);
|
|
if (c == ')') {
|
|
const mul_parsed = parse_mul(match_mul_str.items) catch |err| {
|
|
return err;
|
|
};
|
|
sum += if (mul_parsed < 0) 0 else @intCast(mul_parsed);
|
|
|
|
matching_mul = false;
|
|
match_mul_str.clearRetainingCapacity();
|
|
}
|
|
} else if (c == 'm' and !mul_lock) {
|
|
try match_mul_str.append(ally, c);
|
|
matching_mul = true;
|
|
matching_mul_ind = @intCast(i);
|
|
}
|
|
|
|
if (matching_do) {
|
|
if (c != 'd' and c != 'o' and c != 'n' and c != '\'' and c != 't' and c != '(' and c != ')') {
|
|
matching_do = false;
|
|
match_do_str.clearRetainingCapacity();
|
|
continue;
|
|
}
|
|
|
|
try match_do_str.append(ally, c);
|
|
if (c == ')') {
|
|
const do_parsed = parse_do(match_do_str.items) catch |err| {
|
|
return err;
|
|
};
|
|
mul_lock = if (do_parsed == 1) false else if (do_parsed == -1) true else mul_lock;
|
|
|
|
matching_do = false;
|
|
match_do_str.clearRetainingCapacity();
|
|
}
|
|
} else if (c == 'd') {
|
|
try match_do_str.append(ally, c);
|
|
matching_do = true;
|
|
matching_do_ind = @intCast(i);
|
|
}
|
|
}
|
|
}
|
|
std.debug.print("{}\n", .{sum});
|
|
}
|