wash day05
This commit is contained in:
parent
0f2044b762
commit
0ab1fa186d
@ -20,7 +20,6 @@ fn Range(comptime T: type) type {
|
||||
pub fn intersect(self: Self, other: Self) ?Self {
|
||||
const a = if (self.start < other.start) self else other;
|
||||
const b = if (self.start < other.start) other else self;
|
||||
// std.debug.print("{any}/{any}\n", .{ a, b });
|
||||
|
||||
if (a.start == a.end or b.start == b.end) return null; // Points don't intersect.
|
||||
|
||||
@ -32,29 +31,12 @@ fn Range(comptime T: type) type {
|
||||
/// Returns the union of two ranges.
|
||||
pub fn join(self: Self, other: Self) ?Self {
|
||||
if (self.intersect(other) == null) return null; // Can't union disjoint ranges.
|
||||
// std.debug.print("merge {any}+{any}\n", .{ self, other });
|
||||
// Now guaranteed that they overlap.
|
||||
const merged = Self{ .start = @min(self.start, other.start), .end = @max(self.end, other.end) };
|
||||
std.debug.print("= {any}\n", .{merged});
|
||||
return merged;
|
||||
return .{ .start = @min(self.start, other.start), .end = @max(self.end, other.end) };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "range intersect" {
|
||||
const R = Range(usize);
|
||||
const e = .{ .start = 2, .end = 5 };
|
||||
// Superset
|
||||
try std.testing.expectEqual(e, (R{ .start = 0, .end = 6 }).intersect(.{ .start = 2, .end = 5 }));
|
||||
try std.testing.expectEqual(e, (R{ .start = 2, .end = 5 }).intersect(.{ .start = 0, .end = 6 }));
|
||||
// A < B
|
||||
try std.testing.expectEqual(e, (R{ .start = 0, .end = 5 }).intersect(.{ .start = 2, .end = 6 }));
|
||||
// B < A
|
||||
try std.testing.expectEqual(e, (R{ .start = 2, .end = 6 }).intersect(.{ .start = 0, .end = 5 }));
|
||||
// No intersect
|
||||
try std.testing.expect(null == (R{ .start = 0, .end = 3 }).intersect(.{ .start = 4, .end = 6 }));
|
||||
}
|
||||
|
||||
const Map = struct {
|
||||
offset: isize,
|
||||
source: Range(usize),
|
||||
@ -84,17 +66,6 @@ fn mergeRanges(ranges: *std.ArrayList(Component)) void {
|
||||
}
|
||||
}
|
||||
|
||||
test "mergeRanges" {
|
||||
var ranges = std.ArrayList(Component).init(std.testing.allocator);
|
||||
defer ranges.deinit();
|
||||
try ranges.append(.{ .stage = 0, .range = .{ .start = 79, .end = 93 } });
|
||||
try ranges.append(.{ .stage = 0, .range = .{ .start = 55, .end = 66 } });
|
||||
try ranges.append(.{ .stage = 0, .range = .{ .start = 70, .end = 10 } });
|
||||
mergeRanges(&ranges);
|
||||
try std.testing.expectEqual(.{ .start = 70, .end = 93 }, ranges.items[0].range);
|
||||
try std.testing.expectEqual(.{ .start = 55, .end = 66 }, ranges.items[1].range);
|
||||
}
|
||||
|
||||
fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||
var it = util.splitLines(input);
|
||||
const seed_line = it.next().?;
|
||||
@ -103,10 +74,8 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||
|
||||
var ranges = std.ArrayList(Component).init(alloc);
|
||||
defer ranges.deinit();
|
||||
var lowest_location: usize = std.math.maxInt(usize);
|
||||
|
||||
{
|
||||
std.debug.print("= seeding {d} =\n", .{seeds.len});
|
||||
var index: usize = 0;
|
||||
while (index < seeds.len) : (index += 2) {
|
||||
try ranges.append(.{
|
||||
@ -122,7 +91,6 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||
var current_stage: usize = 0;
|
||||
while (it.next()) |line| {
|
||||
if (line.len == 0) {
|
||||
std.debug.print("== finalise ==\n", .{});
|
||||
for (ranges.items, 0..) |item, index| {
|
||||
if (item.stage != current_stage) {
|
||||
ranges.items[index] = .{ .stage = current_stage, .range = item.range };
|
||||
@ -132,7 +100,6 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||
} else if (mem.endsWith(u8, line, "map:")) {
|
||||
current_stage += 1;
|
||||
} else {
|
||||
std.debug.print("== stage {d} map {s} ==\n", .{ current_stage, line });
|
||||
const map_line = try util.parseIntsScalar(usize, alloc, line, .{});
|
||||
defer alloc.free(map_line);
|
||||
const map = Map{
|
||||
@ -144,40 +111,34 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||
while (i != 0) : (i -= 1) {
|
||||
if (ranges.items[i - 1].stage == current_stage) continue;
|
||||
const item = ranges.swapRemove(i - 1);
|
||||
std.debug.print("item {d}/{d} {d}..{d}\n", .{ i, ranges.items.len + 1, item.range.start, item.range.end });
|
||||
|
||||
if (item.range.intersect(.{ .start = 0, .end = map.source.start })) |section| {
|
||||
// Non-transitioning section.
|
||||
std.debug.print("=> s {d}..{d}\n", .{ section.start, section.end });
|
||||
try ranges.append(.{ .stage = item.stage, .range = section });
|
||||
}
|
||||
if (item.range.intersect(map.source)) |section| {
|
||||
// Transitioning section.
|
||||
const range = Range(usize){
|
||||
.start = @intCast(@as(isize, @intCast(section.start)) + map.offset),
|
||||
.end = @intCast(@as(isize, @intCast(section.end)) + map.offset),
|
||||
};
|
||||
std.debug.print("=> m {d}..{d}\n", .{ range.start, range.end });
|
||||
try ranges.append(.{
|
||||
.stage = current_stage,
|
||||
.range = range,
|
||||
.range = .{
|
||||
.start = @intCast(@as(isize, @intCast(section.start)) + map.offset),
|
||||
.end = @intCast(@as(isize, @intCast(section.end)) + map.offset),
|
||||
},
|
||||
});
|
||||
}
|
||||
if (item.range.intersect(.{ .start = map.source.end, .end = std.math.maxInt(usize) })) |section| {
|
||||
// Non-transitioning section.
|
||||
std.debug.print("=> e {d}..{d}\n", .{ section.start, section.end });
|
||||
try ranges.append(.{ .stage = item.stage, .range = section });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var min_loc: usize = std.math.maxInt(usize);
|
||||
for (ranges.items) |item| {
|
||||
std.debug.print("{any}\n", .{item.range});
|
||||
lowest_location = @min(lowest_location, item.range.start);
|
||||
min_loc = @min(min_loc, item.range.start);
|
||||
}
|
||||
|
||||
return lowest_location;
|
||||
return min_loc;
|
||||
}
|
||||
|
||||
test "silver" {
|
||||
|
Loading…
Reference in New Issue
Block a user