1
Fork 0
mirror of https://github.com/thegeneralist01/aoc synced 2026-03-07 10:59:54 +01:00
aoc/day3/day3_part2.zig
2024-12-03 16:49:17 +01:00

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