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