const std = @import("std"); pub fn main() !void { const file = try std.fs.cwd().openFile("./data.txt", .{}); defer file.close(); var buffer: [40000]u8 = undefined; _ = try file.readAll(&buffer); var it = std.mem.split(u8, &buffer, "\n"); var total1: u64 = 0; var total2: u64 = 0; while (it.next()) |line| { std.debug.print("line: {s}\n", .{line}); if (!std.ascii.isAlphanumeric(line[0])) { continue; } var first: ?u8 = null; var last: ?u8 = null; // Part 1 for (line, 0..) |char, idx| { if (std.ascii.isDigit(char)) { var str = line[idx .. idx + 1]; const parsed = try std.fmt.parseInt(u8, str, 10); if (first == null) { first = parsed; } last = parsed; } } total1 += (first orelse 0) * 10 + (last orelse 0); first = null; last = null; // Part 2 for (line, 0..) |_, idx| { if (matchDigit(line[idx..line.len])) |parsed| { std.debug.print("parsed: {any}\n", .{parsed}); if (first == null) { first = parsed; } last = parsed; } } total2 += (first orelse 0) * 10 + (last orelse 0); } std.debug.print("part 1 total: {any}\n", .{total1}); std.debug.print("part 2 total: {any}\n", .{total2}); } pub fn matchDigit(str: []const u8) ?u8 { // is the first char a digit? if so, return it if (std.ascii.isDigit(str[0])) { const digit = std.fmt.parseInt(u8, str[0..1], 10) catch 0; return digit; } else { const words = [_][]const u8{ "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; for (words, 0..) |word, idx| { if (startsWith(str, word)) { return @intCast(idx + 1); } } } return null; } // does the outer string start with the inner string pub fn startsWith(outer: []const u8, inner: []const u8) bool { if (outer.len < inner.len) { return false; } for (inner, 0..) |c, idx| { if (c != outer[idx]) { return false; } } return true; }