const std = @import("std"); const PATH = "inputs/day01.txt"; const InputType = i24; pub fn first(allocator: std.mem.Allocator) !usize { // Get input const INPUT_SIZE = 1000 * 14; // lines*line_length var buf: [INPUT_SIZE]u8 = undefined; const input = try std.fs.cwd().readFile(PATH, &buf); const lists = try parseInput(allocator, input); defer allocator.free(lists.left); defer allocator.free(lists.right); // Sort both lists std.sort.pdq(InputType, lists.left, {}, std.sort.asc(InputType)); std.sort.pdq(InputType, lists.right, {}, std.sort.asc(InputType)); // Calculate total distance var total_distance: usize = 0; for (lists.left, lists.right) |left, right| { const distance = @abs(left - right); total_distance += distance; } return total_distance; } pub fn second(allocator: std.mem.Allocator) !usize { // Get input const INPUT_SIZE = 1000 * 14; // lines*line_length var buf: [INPUT_SIZE]u8 = undefined; const input = try std.fs.cwd().readFile(PATH, &buf); const lists = try parseInput(allocator, input); defer allocator.free(lists.left); defer allocator.free(lists.right); // Sort right list for efficient matching std.sort.pdq(InputType, lists.right, {}, comptime std.sort.asc(InputType)); // Calculate similarity score var total_score: usize = 0; for (lists.left) |left_num| { var matches: usize = 0; for (lists.right) |right_num| { if (right_num > left_num) break; // No more possible matches if (right_num == left_num) matches += 1; } total_score += @as(usize, @intCast(left_num)) * matches; } return total_score; } fn parseInput(allocator: std.mem.Allocator, input: []const u8) !struct { left: []InputType, right: []InputType, } { var left_list = std.ArrayList(InputType).init(allocator); errdefer left_list.deinit(); var right_list = std.ArrayList(InputType).init(allocator); errdefer right_list.deinit(); var lines = std.mem.tokenize(u8, input, "\n"); while (lines.next()) |line| { var numbers = std.mem.tokenize(u8, line, " \t"); if (numbers.next()) |left| { try left_list.append(try std.fmt.parseInt(InputType, left, 10)); } if (numbers.next()) |right| { try right_list.append(try std.fmt.parseInt(InputType, right, 10)); } } std.debug.assert(left_list.items.len == right_list.items.len); return .{ .left = try left_list.toOwnedSlice(), .right = try right_list.toOwnedSlice(), }; } test "day01a" { try std.testing.expectEqual(@as(usize, 1660292), try first(std.testing.allocator)); } test "day01b" { try std.testing.expectEqual(@as(usize, 22776016), try second(std.testing.allocator)); }