You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.3 KiB
Zig

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