Compare commits
3 commits
9ad1671195
...
3da92e4f2b
| Author | SHA1 | Date | |
|---|---|---|---|
| 3da92e4f2b | |||
| e82fb0a304 | |||
| 9dd5b41fe5 |
2 changed files with 1365 additions and 2 deletions
|
|
@ -1,7 +1,182 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const title = "Day 05";
|
||||
pub const title = "Day 05: Cafeteria";
|
||||
|
||||
pub fn run(_: std.mem.Allocator) !void {
|
||||
pub fn run(allocator: std.mem.Allocator) !void {
|
||||
const input = @embedFile("./input/day05.txt");
|
||||
//const input =
|
||||
// \\3-5
|
||||
// \\10-14
|
||||
// \\16-20
|
||||
// \\12-18
|
||||
// \\
|
||||
// \\1
|
||||
// \\5
|
||||
// \\8
|
||||
// \\11
|
||||
// \\17
|
||||
// \\32
|
||||
// ;
|
||||
//const input =
|
||||
// \\383043617664892-389277822354893
|
||||
// \\387921155483286-389277822354893
|
||||
// ;
|
||||
|
||||
var lines = std.mem.tokenizeScalar(u8, input, '\n');
|
||||
|
||||
var ranges: std.ArrayList(Range) = .empty;
|
||||
defer ranges.deinit(allocator);
|
||||
|
||||
var accumulator: u64 = 0;
|
||||
|
||||
var i: usize = 0;
|
||||
while (lines.next()) |line| {
|
||||
var components = std.mem.tokenizeScalar(u8, line, '-');
|
||||
|
||||
const start_s = components.next() orelse continue;
|
||||
const end_s = components.next() orelse break;
|
||||
const range = Range{
|
||||
.start = try std.fmt.parseUnsigned(u64, start_s, 10),
|
||||
.end = try std.fmt.parseUnsigned(u64, end_s, 10),
|
||||
};
|
||||
|
||||
std.debug.print("==> range {d}\n", .{i});
|
||||
|
||||
processRange(range, ranges.items, &accumulator, 0);
|
||||
|
||||
try ranges.append(allocator, range);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
var buffer: [64]u8 = undefined;
|
||||
var stdout_writer = std.fs.File.stdout().writer(&buffer);
|
||||
const stdout = &stdout_writer.interface;
|
||||
|
||||
try stdout.print("{d}\n", .{accumulator});
|
||||
|
||||
try stdout.flush();
|
||||
}
|
||||
|
||||
fn processRange(
|
||||
range: Range,
|
||||
ranges: []Range,
|
||||
accumulator: *u64,
|
||||
level: usize,
|
||||
) void {
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("recursion level = {d}\n", .{level});
|
||||
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("considering {f}\n", .{range});
|
||||
|
||||
var overlapped = false;
|
||||
for (ranges) |other| {
|
||||
const difference = range.symmetricDifference(other);
|
||||
if (difference.overlapping) {
|
||||
overlapped = true;
|
||||
|
||||
if (range.eql(other)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("- overlaps with {f}\n", .{other});
|
||||
|
||||
if (difference.left != null and difference.right != null) {
|
||||
const left = difference.left.?;
|
||||
const right = difference.right.?;
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("- left = {f}, right = {f}\n", .{left, right});
|
||||
if (left.eql(right)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (left.start == range.start) {
|
||||
processRange(left, ranges, accumulator, level + 1);
|
||||
}
|
||||
if (right.end == range.end) {
|
||||
processRange(right, ranges, accumulator, level + 1);
|
||||
}
|
||||
} else if (difference.left) |left| {
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("- left = {f}\n", .{left});
|
||||
if (left.start == range.start) {
|
||||
processRange(left, ranges, accumulator, level + 1);
|
||||
}
|
||||
} else if (difference.right) |right| {
|
||||
for (0..level) |_| std.debug.print("\t", .{});
|
||||
std.debug.print("- right = {f}\n", .{right});
|
||||
if (right.end == range.end) {
|
||||
processRange(right, ranges, accumulator, level + 1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!overlapped) {
|
||||
const n = (range.end + 1) - range.start;
|
||||
std.debug.print("- no overlap with other range, adding {d}\n", .{n});
|
||||
accumulator.* += n;
|
||||
}
|
||||
}
|
||||
|
||||
const Range = struct {
|
||||
start: u64,
|
||||
end: u64,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub const SymmetricDifference = struct {
|
||||
left: ?Self = null,
|
||||
right: ?Self = null,
|
||||
overlapping: bool,
|
||||
};
|
||||
|
||||
pub fn format(self: Range, w: *std.io.Writer) std.io.Writer.Error!void {
|
||||
try w.print("{d} to {d}", .{self.start, self.end});
|
||||
}
|
||||
|
||||
pub fn eql(self: Self, other: Self) bool {
|
||||
return self.start == other.start and self.end == other.end;
|
||||
}
|
||||
|
||||
pub fn symmetricDifference(self: Self, other: Self) SymmetricDifference {
|
||||
const overlapping = self.start <= other.end and self.end >= other.start;
|
||||
if (!overlapping) {
|
||||
const left, const right = if (self.end < other.start) .{ self, other } else .{ other, self };
|
||||
return .{
|
||||
.left = left,
|
||||
.right = right,
|
||||
.overlapping = overlapping,
|
||||
};
|
||||
}
|
||||
|
||||
var difference: SymmetricDifference = .{ .overlapping = overlapping };
|
||||
if (self.start < other.start) {
|
||||
difference.left = .{
|
||||
.start = self.start,
|
||||
.end = other.start - 1,
|
||||
};
|
||||
} else if (other.start < self.start) {
|
||||
difference.left = .{
|
||||
.start = other.start,
|
||||
.end = self.start - 1,
|
||||
};
|
||||
}
|
||||
if (self.end > other.end) {
|
||||
difference.right = .{
|
||||
.start = other.end + 1,
|
||||
.end = self.end,
|
||||
};
|
||||
} else if (other.end > self.end) {
|
||||
difference.right = .{
|
||||
.start = self.end + 1,
|
||||
.end = other.end,
|
||||
};
|
||||
}
|
||||
return difference;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
1188
src/days/input/day05.txt
Executable file
1188
src/days/input/day05.txt
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue