Compare commits

...

2 Commits

Author SHA1 Message Date
8f9891cdde add showing time taken for each solution 2023-12-16 14:02:51 +02:00
676dceec14 solve day 6 2023-12-16 13:51:12 +02:00
3 changed files with 123 additions and 2 deletions

View File

@ -1,6 +1,5 @@
const aoc = @import("./aoc.zig");
const std = @import("std");
const expect = std.testing.expect;
const MappingRange = struct {
src_start: u64,

115
src/day6.zig Normal file
View File

@ -0,0 +1,115 @@
const std = @import("std");
const aoc = @import("./aoc.zig");
const assert = std.debug.assert;
const BoundedU32 = std.BoundedArray(u32, 32);
const Input = struct {
time: BoundedU32,
distance: BoundedU32,
};
fn parse_numbers(result: *BoundedU32, text: []const u8) !void {
var i: usize = 0;
var tokens = std.mem.tokenizeScalar(u8, text, ' ');
while (tokens.next()) |token| : (i += 1) {
const number = try std.fmt.parseInt(u32, token, 10);
try result.append(number);
}
}
fn parse_input(lines: []const []const u8) !Input {
var time = try BoundedU32.init(0);
var distance = try BoundedU32.init(0);
try parse_numbers(&time, lines[0][9..]);
try parse_numbers(&distance, lines[1][9..]);
assert(time.len == distance.len);
return Input{ .time = time, .distance = distance };
}
pub fn part1(input: *aoc.Input) !aoc.Result {
var parsed = try parse_input(input.lines);
var answer: u32 = 1;
for (0..parsed.time.len) |i| {
const required_distance = parsed.distance.get(i);
const max_allowed_time = parsed.time.get(i);
var min_time: u32 = 0;
var max_time: u32 = 0;
for (1..(max_allowed_time+1)) |speed_usize| {
const speed: u32 = @intCast(speed_usize);
const distance = speed*(max_allowed_time - speed);
if (distance <= required_distance) continue;
if (max_time == 0) {
min_time = speed;
max_time = speed;
} else {
max_time = @max(max_time, speed);
}
}
const margin = max_time - min_time + 1;
answer *= margin;
}
return .{ .uint = answer };
}
pub fn part2(input: *aoc.Input) !aoc.Result {
var parsed = try parse_input(input.lines);
var allowed_time: u64 = 0;
var required_distance: u64 = 0;
for (0..parsed.time.len) |i| {
const time = parsed.time.get(i);
if (allowed_time > 0) {
allowed_time *= try std.math.powi(u32, 10, std.math.log10(time)+1);
}
allowed_time += time;
const distance = parsed.distance.get(i);
if (required_distance > 0) {
required_distance *= try std.math.powi(u32, 10, std.math.log10(distance)+1);
}
required_distance += distance;
}
var min_time: u64 = 0;
var max_time: u64 = 0;
for (1..(allowed_time+1)) |speed_usize| {
const speed: u64 = @intCast(speed_usize);
const distance = speed*(allowed_time - speed);
if (distance <= required_distance) continue;
if (max_time == 0) {
min_time = speed;
max_time = speed;
} else {
max_time = @max(max_time, speed);
}
}
var answer = max_time - min_time + 1;
return .{ .uint = @intCast(answer) };
}
const example_input = [_][]const u8{
"Time: 7 15 30",
"Distance: 9 40 200"
};
test "part 1 example" {
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
var actual = try part1(&input);
var expected: u32 = 288;
try std.testing.expectEqual(expected, actual.uint);
}
test "part 2 example" {
var input = aoc.Input{ .lines = &example_input, .allocator = std.testing.allocator };
var actual = try part2(&input);
var expected: u32 = 71503;
try std.testing.expectEqual(expected, actual.uint);
}

View File

@ -26,6 +26,7 @@ const Days = [_]aoc.Day{
create_day(@import("day3.zig")),
create_day(@import("day4.zig")),
create_day(@import("day5.zig")),
create_day(@import("day6.zig")),
};
fn kilobytes(count: u32) u32 {
@ -72,6 +73,7 @@ fn run(allocator: Allocator, args: *cli) !u8 {
var input = aoc.Input{ .allocator = allocator, .lines = lines.items };
var start_time = std.time.microTimestamp();
var result: aoc.Result = undefined;
if (args.part == 1) {
result = try day.part1.?(&input);
@ -80,6 +82,7 @@ fn run(allocator: Allocator, args: *cli) !u8 {
} else {
unreachable;
}
const end_time = std.time.microTimestamp();
switch (result) {
.uint => std.debug.print("{}\n", .{result.uint}),
@ -88,6 +91,9 @@ fn run(allocator: Allocator, args: *cli) !u8 {
.text => std.debug.print("{s}\n", .{result.text}),
}
const duration = end_time - start_time;
std.debug.print("Time taken: {}ms ({}us)\n", .{@divTrunc(duration, std.time.us_per_ms), duration});
return 0;
}
@ -135,7 +141,7 @@ fn get_input(allocator: Allocator, args: *cli) !u8 {
return 255;
}
const body = try request.reader().readAllAlloc(allocator, kilobytes(8));
const body = try request.reader().readAllAlloc(allocator, kilobytes(128));
defer allocator.free(body);
var file = try std.fs.cwd().createFile(args.input_file, .{ });
@ -172,4 +178,5 @@ test {
_ = @import("day3.zig");
_ = @import("day4.zig");
_ = @import("day5.zig");
_ = @import("day6.zig");
}