I’m going to try a few solutions this year in Zig. I spent some time with this one, to break it into readable functions. I wrote up some notes about my solution: Aoc2024Day1
My solution
const std = @import("std");
pub fn main() !void {
// get allocator
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena.allocator();
defer _ = arena.deinit();
// get command-line args
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
// see if filename is on command-line
if (args.len == 2) {
const filename = args[1];
solveDay(allocator, filename) catch |err| {
switch (err) {
error.FileNotFound => {
std.debug.print("Error: File {s} was not found.\n", .{filename});
std.process.exit(1);
},
else => {
std.debug.print("Error: in processing file.\n", .{});
std.process.exit(1);
},
}
};
} else {
std.debug.print("Provide a filename of input data.\n", .{});
}
}
fn solveDay (allocator: std.mem.Allocator, filename: []const u8) !void {
// put the numbers in two lists, one per column
var column1 = std.ArrayList(usize).init(allocator);
var column2 = std.ArrayList(usize).init(allocator);
try readData(allocator, filename, &column1, &column2);
// sort the two columns
std.mem.sort(usize, column1.items, {}, comptime std.sort.asc(usize));
std.mem.sort(usize, column2.items, {}, comptime std.sort.asc(usize));
std.debug.print("Part 1: {d}\n", .{totalDifference(&column1, &column2)});
std.debug.print("Part 2: {d}\n", .{totalSimilarity(&column1, &column2)});
}
fn totalDifference(column1: *std.ArrayList(usize), column2: *std.ArrayList(usize)) usize {
var result : usize = 0;
for (column1.items, column2.items) |left, right| {
if (left > right) {
result += left - right;
} else {
result += right - left;
}
}
return result;
}
fn totalSimilarity(column1: *std.ArrayList(usize), column2: *std.ArrayList(usize)) usize {
var result: usize = 0;
for (column1.items) |left| {
result += left * std.mem.count(usize, column2.items, &[_]usize{left});
}
return result;
}
// Read in the two columns of data from given filename
fn readData (allocator: std.mem.Allocator, filename: []const u8,
column1: *std.ArrayList(usize), column2: *std.ArrayList(usize)) !void {
const file = try std.fs.cwd().openFile(filename, .{});
defer file.close();
const stat = try file.stat();
const data = try file.readToEndAlloc(allocator, stat.size);
var lines = std.mem.tokenize(u8, data, "\n");
while (lines.next()) |line| {
var columns = std.mem.tokenize(u8, line, " ");
const number1 = try std.fmt.parseInt(usize, columns.next() orelse return, 10);
const number2 = try std.fmt.parseInt(usize, columns.next() orelse return, 10);
try column1.append(number1);
try column2.append(number2);
}
}