78 lines
2.3 KiB
Zig
78 lines
2.3 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn main() anyerror!void {
|
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
defer arena.deinit();
|
|
const alloc = &arena.allocator;
|
|
|
|
// Read our input
|
|
var f = try std.fs.cwd().openFile("input", .{});
|
|
defer f.close();
|
|
var contents = try f.readToEndAlloc(alloc, std.math.maxInt(u32));
|
|
defer alloc.free(contents);
|
|
|
|
var values = std.ArrayList(u16).init(alloc);
|
|
defer values.deinit();
|
|
var it = std.mem.tokenize(contents, "\n");
|
|
while (it.next()) |line| {
|
|
var lit = std.mem.tokenize(line, ",");
|
|
while (lit.next()) |value| {
|
|
try values.append(try std.fmt.parseInt(u16, value, 10));
|
|
}
|
|
}
|
|
//std.log.debug("{} items", .{values.items.len});
|
|
std.sort.sort(u16, values.items, {}, comptime std.sort.asc(u16));
|
|
//std.log.debug("{any}", .{values.items});
|
|
|
|
// Try the median
|
|
var median = values.items[values.items.len/2];
|
|
std.log.debug("Median position {}, value: {}",
|
|
.{values.items.len/2, median});
|
|
|
|
var fuel_required: u64 = 0;
|
|
for (values.items) |v| {
|
|
if (v < median) {
|
|
fuel_required += @as(u64, median - v);
|
|
}
|
|
else {
|
|
fuel_required += @as(u64, v - median);
|
|
}
|
|
}
|
|
std.log.info("[Part 1] {} fuel required to get to median {}",
|
|
.{fuel_required, median});
|
|
|
|
var i = values.items[0];
|
|
const max = values.items[values.items.len-1];
|
|
fuel_required = std.math.maxInt(u32);
|
|
var best_position: u16 = 0;
|
|
while (i <= max) : (i += 1) {
|
|
var fu = calculate_fuel_to_pos(i, values.items[0..]);
|
|
if (fu < fuel_required) {
|
|
fuel_required = fu;
|
|
best_position = 1;
|
|
}
|
|
}
|
|
std.log.info("[Part 2] {} fuel required to get to best pos {}",
|
|
.{fuel_required, best_position});
|
|
}
|
|
|
|
// move 1: 1 = 1
|
|
// move 2: 1 + 2 = 3
|
|
// move 3: 1 + 2 + 3 = 6
|
|
// move 4: (1+2+3)+4 = 10
|
|
// move n: (1/2)n * (n+1)
|
|
fn calculate_fuel_to_pos(position: u16, crabs: []u16) u64 {
|
|
var fuel_required: u64 = 0;
|
|
for (crabs) |c| {
|
|
var delta: u64 = 0;
|
|
if (c < position) {
|
|
delta = @as(u64, position - c);
|
|
}
|
|
else {
|
|
delta = @as(u64, c - position);
|
|
}
|
|
fuel_required += (delta*(delta+1)) / 2;
|
|
}
|
|
return fuel_required;
|
|
}
|