Compare commits
2 Commits
77ff15f997
...
8f9891cdde
Author | SHA1 | Date | |
---|---|---|---|
8f9891cdde | |||
676dceec14 |
@ -1,6 +1,5 @@
|
|||||||
const aoc = @import("./aoc.zig");
|
const aoc = @import("./aoc.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const expect = std.testing.expect;
|
|
||||||
|
|
||||||
const MappingRange = struct {
|
const MappingRange = struct {
|
||||||
src_start: u64,
|
src_start: u64,
|
||||||
|
115
src/day6.zig
Normal file
115
src/day6.zig
Normal 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);
|
||||||
|
}
|
@ -26,6 +26,7 @@ const Days = [_]aoc.Day{
|
|||||||
create_day(@import("day3.zig")),
|
create_day(@import("day3.zig")),
|
||||||
create_day(@import("day4.zig")),
|
create_day(@import("day4.zig")),
|
||||||
create_day(@import("day5.zig")),
|
create_day(@import("day5.zig")),
|
||||||
|
create_day(@import("day6.zig")),
|
||||||
};
|
};
|
||||||
|
|
||||||
fn kilobytes(count: u32) u32 {
|
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 input = aoc.Input{ .allocator = allocator, .lines = lines.items };
|
||||||
|
|
||||||
|
var start_time = std.time.microTimestamp();
|
||||||
var result: aoc.Result = undefined;
|
var result: aoc.Result = undefined;
|
||||||
if (args.part == 1) {
|
if (args.part == 1) {
|
||||||
result = try day.part1.?(&input);
|
result = try day.part1.?(&input);
|
||||||
@ -80,6 +82,7 @@ fn run(allocator: Allocator, args: *cli) !u8 {
|
|||||||
} else {
|
} else {
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
const end_time = std.time.microTimestamp();
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
.uint => std.debug.print("{}\n", .{result.uint}),
|
.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}),
|
.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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +141,7 @@ fn get_input(allocator: Allocator, args: *cli) !u8 {
|
|||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = try request.reader().readAllAlloc(allocator, kilobytes(8));
|
const body = try request.reader().readAllAlloc(allocator, kilobytes(128));
|
||||||
defer allocator.free(body);
|
defer allocator.free(body);
|
||||||
|
|
||||||
var file = try std.fs.cwd().createFile(args.input_file, .{ });
|
var file = try std.fs.cwd().createFile(args.input_file, .{ });
|
||||||
@ -172,4 +178,5 @@ test {
|
|||||||
_ = @import("day3.zig");
|
_ = @import("day3.zig");
|
||||||
_ = @import("day4.zig");
|
_ = @import("day4.zig");
|
||||||
_ = @import("day5.zig");
|
_ = @import("day5.zig");
|
||||||
|
_ = @import("day6.zig");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user