solve day 6

This commit is contained in:
Rokas Puzonas 2023-12-16 13:51:12 +02:00
parent 77ff15f997
commit 676dceec14
3 changed files with 117 additions and 1 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 {
@ -172,4 +173,5 @@ test {
_ = @import("day3.zig");
_ = @import("day4.zig");
_ = @import("day5.zig");
_ = @import("day6.zig");
}