const std = @import("std");
const Str = []const u8;
const PATH = "input/day05.txt";
pub fn first(allocator: std.mem.Allocator) !usize {
_ = allocator;
var lines = std.mem.tokenize(u8, @embedFile(PATH), "\n");
var ret: usize = 0;
while (lines.next()) |line| {
if (checkLine(line)) ret += 1;
}
return ret;
}
pub fn second(allocator: std.mem.Allocator) !usize {
_ = allocator;
var lines = std.mem.tokenize(u8, @embedFile(PATH), "\n");
var ret: usize = 0;
while (lines.next()) |line| {
if (checkLine2(line)) ret += 1;
}
return ret;
}
fn checkLine(line: Str) bool {
var vowels: usize = 0;
var double: bool = false;
for (line) |ch, idx| {
// vowels
switch (ch) {
'a', 'e', 'i', 'o', 'u' => vowels += 1,
else => {},
}
// index underrun
if (idx == 0) continue;
// bad combinations
switch (ch) {
'b', 'd', 'q', 'y' => {
if (ch - 1 == line[idx - 1]) return false;
},
else => {},
}
// doubles
if (ch == line[idx - 1]) double = true;
}
return double and (vowels > 2);
}
fn checkLine2(line: Str) bool {
var repeat: bool = false;
var pair: bool = false;
for (line) |ch, idx| {
// pair
if (idx == 0) continue;
if (!pair) {
const sub_line = if (idx + 2 < line.len) line[idx + 1 ..] else "";
for (sub_line) |sch, sidx| {
if (sidx == sub_line.len - 1) break;
// std.debug.print("{c}{c} - {c}{c}\n", .{ line[idx - 1], ch, sch, sub_line[sidx + 1] });
if (ch == sub_line[sidx + 1] and line[idx - 1] == sch) {
pair = true;
break;
}
}
}
// repeat check
if (idx < 2) continue;
if (ch == line[idx - 2]) repeat = true;
if (repeat and pair) return true;
}
return false;
}
test "checkLine" {
try std.testing.expectEqual(true, checkLine("ugknbfddgicrmopn"));
try std.testing.expectEqual(true, checkLine("aaa"));
try std.testing.expectEqual(false, checkLine("jchzalrnumimnmhp"));
try std.testing.expectEqual(false, checkLine("haegwjzuvuyypxyu"));
try std.testing.expectEqual(false, checkLine("dvszwmarrgswjxmb"));
}
test "checkLine - Part 2" {
try std.testing.expectEqual(true, checkLine2("qjhvhtzxzqqjkmpb"));
try std.testing.expectEqual(true, checkLine2("xxyxx"));
try std.testing.expectEqual(false, checkLine2("uurcxstgmygtbstg"));
try std.testing.expectEqual(false, checkLine2("ieodomkazucvgmuy"));
}
test "day05a" {
try std.testing.expectEqual(@as(usize, 236), try first(std.testing.allocator));
}
test "day05b" {
try std.testing.expectEqual(@as(usize, 51), try second(std.testing.allocator));
}