const std = @import("std"); const PATH = "input/day13.txt"; const Str = []const u8; pub fn first(allocator: ?std.mem.Allocator) anyerror!usize { const shuttle = try parseInput1(allocator.?, @embedFile(PATH)); defer allocator.?.free(shuttle.buses); var min: usize = std.math.maxInt(usize); var min_bus: usize = undefined; for (shuttle.buses) |bus| { const departures: usize = shuttle.dep / bus; const diff = bus * (departures + 1) - shuttle.dep; if (diff < min) { min = diff; min_bus = bus; } } return min * min_bus; } pub fn second(allocator: ?std.mem.Allocator) anyerror!usize { const buses = try parseInput2(allocator.?, @embedFile(PATH)); defer allocator.?.free(buses); var diff: usize = buses[0].num; var candidate: usize = 0; for (buses[1..]) |bus| { while ((candidate + bus.offset) % bus.num != 0) candidate += diff; diff *= bus.num; } return candidate; } const Shuttle = struct { dep: usize, buses: []usize, }; fn parseInput1(allocator: std.mem.Allocator, input: Str) !Shuttle { var ret: Shuttle = undefined; var lines = std.mem.tokenize(u8, input, "\n"); // parse departure time ret.dep = try std.fmt.parseUnsigned(usize, lines.next().?, 0); // parse buses var bus_array = std.ArrayList(usize).init(allocator); var buses = std.mem.tokenize(u8, lines.next().?, ","); while (buses.next()) |bus| { if (bus[0] == 'x') continue; try bus_array.append(try std.fmt.parseUnsigned(usize, bus, 0)); } ret.buses = try bus_array.toOwnedSlice(); return ret; } const Bus = struct { offset: usize, num: usize, }; fn parseInput2(allocator: std.mem.Allocator, input: Str) ![]Bus { var lines = std.mem.tokenize(u8, input, "\n"); _ = lines.next(); var bus_array = std.ArrayList(Bus).init(allocator); var buses = std.mem.tokenize(u8, lines.next().?, ","); var idx: usize = 0; while (buses.next()) |bus| : (idx += 1) { if (bus[0] == 'x') continue; const b: Bus = .{ .offset = idx, .num = try std.fmt.parseUnsigned(usize, bus, 0) }; try bus_array.append(b); } return bus_array.toOwnedSlice(); } test "day13a" { try std.testing.expectEqual(@as(usize, 161), try first(std.testing.allocator)); } test "day13b" { try std.testing.expectEqual(@as(usize, 213890632230818), try second(std.testing.allocator)); }