Skip to content

Commit 36aba59

Browse files
committed
Day 7 part 2 linear
1 parent abdf20b commit 36aba59

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

day07/part1_linear.zig

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const std = @import("std");
2+
3+
/// This is a refactor of part1.zig that makes it easier to
4+
/// do part2 linearly.
5+
pub fn main() !void {
6+
var file = try std.fs.cwd().openFile("input", .{});
7+
defer file.close();
8+
9+
var buf_reader = std.io.bufferedReader(file.reader());
10+
var in_stream = buf_reader.reader();
11+
12+
var read_buf: [1024 * 64]u8 = undefined;
13+
const line = try in_stream.readUntilDelimiterOrEof(&read_buf, '\n');
14+
var split = std.mem.split(line.?, ",");
15+
16+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
17+
defer arena.deinit();
18+
19+
const allocator = &arena.allocator;
20+
21+
var positions = std.ArrayList(u32).init(allocator);
22+
defer positions.deinit();
23+
24+
// Read all positions.
25+
while (split.next()) |pos_str| {
26+
const pos = try std.fmt.parseInt(u32, pos_str, 10);
27+
try positions.append(pos);
28+
}
29+
30+
var crabs: []u32 = positions.items;
31+
32+
// Sort.
33+
std.sort.sort(u32, crabs, {}, comptime std.sort.asc(u32));
34+
35+
const len: u32 = @truncate(u32, crabs.len);
36+
const min_pos: u32 = crabs[0];
37+
const max_pos: u32 = crabs[len - 1];
38+
39+
var sum_dist_left: i64 = 0;
40+
var sum_dist_right: i64 = 0;
41+
42+
for (crabs) |pos| {
43+
sum_dist_right += pos - min_pos;
44+
}
45+
46+
var min_fuel_pos: u32 = min_pos;
47+
var min_fuel: i64 = sum_dist_left + sum_dist_right;
48+
49+
var pos: u32 = min_pos + 1;
50+
var i: u32 = 0;
51+
while (pos <= max_pos) : (pos += 1) {
52+
while (pos > crabs[i]) {
53+
i += 1;
54+
}
55+
56+
const crabs_left: u32 = i;
57+
const crabs_right: u32 = len - i;
58+
59+
// We are getting further from i crabs,
60+
sum_dist_left += crabs_left;
61+
// closer to (len - i) crabs.
62+
sum_dist_right -= crabs_right;
63+
64+
const total_fuel = sum_dist_left + sum_dist_right;
65+
if (min_fuel > total_fuel) {
66+
min_fuel = total_fuel;
67+
min_fuel_pos = pos;
68+
}
69+
}
70+
71+
const stdout = std.io.getStdOut().writer();
72+
try stdout.print("{d}\n", .{min_fuel});
73+
}

day07/part2_linear.zig

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
const std = @import("std");
2+
3+
/// This is a refactor of part2 that is linear.
4+
pub fn main() !void {
5+
var file = try std.fs.cwd().openFile("input", .{});
6+
defer file.close();
7+
8+
var buf_reader = std.io.bufferedReader(file.reader());
9+
var in_stream = buf_reader.reader();
10+
11+
var read_buf: [1024 * 64]u8 = undefined;
12+
const line = try in_stream.readUntilDelimiterOrEof(&read_buf, '\n');
13+
var split = std.mem.split(line.?, ",");
14+
15+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
16+
defer arena.deinit();
17+
18+
const allocator = &arena.allocator;
19+
20+
var positions = std.ArrayList(u32).init(allocator);
21+
defer positions.deinit();
22+
23+
// Read all positions.
24+
while (split.next()) |pos_str| {
25+
const pos = try std.fmt.parseInt(u32, pos_str, 10);
26+
try positions.append(pos);
27+
}
28+
29+
var crabs: []u32 = positions.items;
30+
31+
// Sort.
32+
std.sort.sort(u32, crabs, {}, comptime std.sort.asc(u32));
33+
34+
const len: u32 = @truncate(u32, crabs.len);
35+
const min_pos: u32 = crabs[0];
36+
const max_pos: u32 = crabs[len - 1];
37+
38+
var sum_dist_left: i64 = 0;
39+
var sum_dist_right: i64 = 0;
40+
41+
var sum_fuel_left: i64 = 0;
42+
var sum_fuel_right: i64 = 0;
43+
44+
for (crabs) |pos| {
45+
const dist = pos - min_pos;
46+
sum_dist_right += dist;
47+
sum_fuel_right += (dist * (dist + 1)) / 2;
48+
}
49+
50+
var min_fuel_pos: u32 = min_pos;
51+
var min_fuel: i64 = sum_fuel_left + sum_fuel_right;
52+
53+
var pos: u32 = min_pos + 1;
54+
var i: u32 = 0;
55+
while (pos <= max_pos) : (pos += 1) {
56+
while (pos > crabs[i]) {
57+
i += 1;
58+
}
59+
60+
const crabs_left: u32 = i;
61+
const crabs_right: u32 = len - i;
62+
63+
// We are getting further from i crabs,
64+
sum_dist_left += crabs_left;
65+
66+
// Crabs on the left would consume as much more
67+
// fuel as their distance.
68+
sum_fuel_left += sum_dist_left;
69+
70+
// Crabs on the right would consume as much less
71+
// fuel as their previous distance.
72+
sum_fuel_right -= sum_dist_right;
73+
74+
// We're getting closer to (len - i) crabs.
75+
sum_dist_right -= crabs_right;
76+
77+
const total_fuel = sum_fuel_left + sum_fuel_right;
78+
if (min_fuel > total_fuel) {
79+
min_fuel = total_fuel;
80+
min_fuel_pos = pos;
81+
}
82+
}
83+
84+
const stdout = std.io.getStdOut().writer();
85+
try stdout.print("{d}\n", .{min_fuel});
86+
}

0 commit comments

Comments
 (0)