const std = @import("std");
const Str = []const u8;
const PATH = "input/day08.txt";
pub fn first(allocator: std.mem.Allocator) !usize {
_ = allocator;
var chars: usize = 0;
var real_chars: usize = 0;
var lines = std.mem.tokenize(u8, @embedFile(PATH), "\n");
while (lines.next()) |line| {
chars += line.len;
real_chars += try realChars(line);
}
return chars - real_chars;
}
pub fn second(allocator: std.mem.Allocator) !usize {
var chars: usize = 0;
var encode_chars: usize = 0;
var encoded = std.ArrayList(u8).init(allocator);
defer encoded.deinit();
var lines = std.mem.tokenize(u8, @embedFile(PATH), "\n");
while (lines.next()) |line| {
chars += line.len;
try encoded.resize(0);
try encodeString(&encoded, line);
encode_chars += encoded.items.len + 2; // leading and trailing double-quotes
}
return encode_chars - chars;
}
fn realChars(line: Str) !usize {
var ret: usize = 0;
var idx: usize = 0;
while (idx < line.len) : (idx += 1) {
switch (line[idx]) {
'"' => {},
'\\' => {
if (line[idx + 1] == '"' or line[idx + 1] == '\\') {
ret += 1;
idx += 1;
} else if (line[idx + 1] == 'x') {
ret += 1;
idx += 3;
}
},
else => ret += 1,
}
}
return ret;
}
fn encodeString(encoded: *std.ArrayList(u8), raw: Str) !void {
var idx: usize = 0;
while (idx < raw.len) : (idx += 1) {
switch (raw[idx]) {
'"' => {
try encoded.appendSlice("\\\"");
},
'\\' => {
try encoded.appendSlice("\\\\");
},
else => try encoded.append(raw[idx]),
}
}
}
const test_input =
\\""
\\"abc"
\\"aaa\"aaa"
\\"\x27"
;
test "day08a" {
try std.testing.expectEqual(@as(usize, 1333), try first(std.testing.allocator));
}
test "day08b" {
try std.testing.expectEqual(@as(usize, 2046), try second(std.testing.allocator));
}