const std = @import("std");
const PATH = "input/day02.txt";
pub fn first(allocator: ?std.mem.Allocator) anyerror!usize {
_ = allocator;
const file = @embedFile(PATH);
var lines = std.mem.tokenize(u8, file, "\n");
var good_pw: usize = 0;
while (lines.next()) |line| {
var pw = std.mem.tokenize(u8, line, ": ");
const pw_minmax = pw.next().?;
var mm = std.mem.tokenize(u8, pw_minmax, "-");
const min = try std.fmt.parseUnsigned(usize, mm.next().?, 0);
const max = try std.fmt.parseUnsigned(usize, mm.next().?, 0);
const pw_char = pw.next().?[0];
const pw_str = pw.next().?;
var counter: usize = 0;
for (pw_str) |ch| {
if (ch == pw_char) counter += 1;
}
if (counter >= min and counter <= max) good_pw += 1;
}
return good_pw;
}
pub fn second(allocator: ?std.mem.Allocator) anyerror!usize {
_ = allocator;
const file = @embedFile(PATH);
var lines = std.mem.tokenize(u8, file, "\n");
var good_pw: usize = 0;
while (lines.next()) |line| {
var pw = std.mem.tokenize(u8, line, ": ");
const pw_minmax = pw.next().?;
var mm = std.mem.tokenize(u8, pw_minmax, "-");
const pos1 = try std.fmt.parseUnsigned(usize, mm.next().?, 0);
const pos2 = try std.fmt.parseUnsigned(usize, mm.next().?, 0);
const pw_char = pw.next().?[0];
const pw_str = pw.next().?;
if ((pw_str[pos1 - 1] == pw_char and pw_str[pos2 - 1] != pw_char) or
(pw_str[pos1 - 1] != pw_char and pw_str[pos2 - 1] == pw_char)) good_pw += 1;
}
return good_pw;
}
test "day02a" {
try std.testing.expectEqual(@as(usize, 572), try first(std.testing.allocator));
}
test "day02b" {
try std.testing.expectEqual(@as(usize, 306), try second(std.testing.allocator));
}