Skip to content

Instantly share code, notes, and snippets.

@sotolf2
Created July 1, 2024 09:25
Show Gist options
  • Save sotolf2/c9460f53a7f3fdce88da546a597b556a to your computer and use it in GitHub Desktop.
Save sotolf2/c9460f53a7f3fdce88da546a597b556a to your computer and use it in GitHub Desktop.
const std = @import("std");
const mem = std.mem;
const fs = std.fs;
const print = std.debug.print;
fn unallocDeinit(self: std.ArrayList([]const u8), alloc: mem.Allocator) void {
for (self.items) |line| {
alloc.free(line);
}
self.deinit();
}
fn getLines(path: []const u8, alloc: mem.Allocator) !std.ArrayList([]const u8) {
const file = fs.cwd().openFile(path, .{}) catch |err| {
std.log.err("Failed to open file {s}", .{@errorName(err)});
return err;
};
defer file.close();
var lines = std.ArrayList([]const u8).init(alloc);
while (file.reader().readUntilDelimiterOrEofAlloc(alloc, '\n', std.math.maxInt(usize)) catch |err| {
std.log.err("Failed to read line: {s}", .{@errorName(err)});
return err;
}) |line| {
try lines.append(line);
}
return lines;
}
const Parser = struct {
line: []const u8,
idx: usize,
fn fromString(line: []const u8) Parser {
return Parser{
.line = line,
.idx = 0,
};
}
fn peek(self: Parser) u8 {
return self.line[self.idx];
}
fn next(self: *Parser) ?u8 {
if (self.idx >= self.line.len) {
return null;
}
self.idx += 1;
return self.line[self.idx - 1];
}
fn getCodeLen(self: Parser) usize {
return self.line.len;
}
fn getStrLen(self: *Parser) usize {
var len: usize = 0;
// reset the parser
self.idx = 0;
while (self.next()) |ch| {
if (ch == '\"') continue;
if (ch == ' ') continue;
if (ch == '\\') {
const next_char = self.peek();
if (next_char == 'x') {
self.idx += 2;
}
self.idx += 1;
}
len += 1;
}
return len;
}
fn getEncodedLen(self: *Parser) usize {
// set len to 2 to include the "" wrapper
var len: usize = 2;
// reset parser
self.idx = 0;
while (self.next()) |ch| {
if (ch == '\"') len += 1;
if (ch == '\\') len += 1;
len += 1;
}
return len;
}
};
fn part1(lines: std.ArrayList([]const u8)) void {
var codelen: usize = 0;
var strlen: usize = 0;
for (lines.items) |line| {
var parser = Parser.fromString(line);
codelen += parser.getCodeLen();
strlen += parser.getStrLen();
}
const score = codelen - strlen;
print("Part1: {d}\n", .{score});
}
fn part2(lines: std.ArrayList([]const u8)) void {
var len_encoded: usize = 0;
var len_str: usize = 0;
for (lines.items) |line| {
var parser = Parser.fromString(line);
len_str += parser.getCodeLen();
len_encoded += parser.getEncodedLen();
}
const score: usize = len_encoded - len_str;
print("Part2: {d}\n", .{score});
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
const filename = "day8.txt";
const lines = try getLines(filename, alloc);
defer unallocDeinit(lines, alloc);
part1(lines);
part2(lines);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment