const std = @import("std"); const builtin = @import("builtin"); fn readInputFile(allocator: std.mem.Allocator, filename: []const u8) anyerror![]u32 { var result = std.ArrayList(u32).init(allocator); const file = try std.fs.cwd().openFile(filename, .{ .read = true }); defer file.close(); const reader = file.reader(); var line: []u8 = undefined; if (builtin.os.tag == .windows) { // NOTE: Read another byte on windows due to two-byte eol. line = reader.readUntilDelimiterAlloc(allocator, '\r', 4096) catch unreachable; _ = try reader.readByte(); } else { line = reader.readUntilDelimiterAlloc(allocator, '\n', 4096) catch unreachable; } defer allocator.free(line); var it = std.mem.split(u8, line, ","); while (it.next()) |slice| { const value = try std.fmt.parseUnsigned(u32, slice, 10); try result.append(value); } return result.items; } const asc_u32 = std.sort.asc(u32); pub fn task1(crabs: []u32) u32 { var result: u32 = 999999; const min = std.sort.min(u32, crabs, {}, asc_u32).?; const max = std.sort.max(u32, crabs, {}, asc_u32).?; var i = min; while (i <= max) : (i += 1) { var fuel_required: u32 = 0; for (crabs) |crab_pos| { fuel_required += if (i <= crab_pos) crab_pos - i else i - crab_pos; } std.log.debug("{}: {} required", .{ i, fuel_required }); if (fuel_required < result) { result = fuel_required; } } return result; } fn calculateFuel(target_position: u32, crabs: []u32) u32 { var result: u32 = 0; for (crabs) |crab_pos| { const distance = if (target_position <= crab_pos) crab_pos - target_position else target_position - crab_pos; var cost: u32 = 0; var i: u32 = 0; while (i <= distance) : (i += 1) { cost += i; } result += cost; } return result; } pub fn task2(crabs: []u32) u64 { var result: u64 = 9999999999; const min = std.sort.min(u32, crabs, {}, asc_u32).?; const max = std.sort.max(u32, crabs, {}, asc_u32).?; var i = min; while (i <= max) : (i += 1) { const fuel_required = calculateFuel(i, crabs); std.log.debug("{}: {} required", .{ i, fuel_required }); if (fuel_required < result) { result = fuel_required; } } return result; } pub fn main() anyerror!void { var buffer: [2000000]u8 = undefined; var fixed_buffer = std.heap.FixedBufferAllocator.init(&buffer); const allocator = fixed_buffer.allocator(); const input = try readInputFile(allocator, "input.txt"); const task_1_result = task1(input); std.log.info("Task 1 result: {}", .{task_1_result}); const task_2_result = task2(input); std.log.info("Task 2 result: {}", .{task_2_result}); }