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 {
|
pub fn intersect(self: Self, other: Self) ?Self {
|
||||||
const a = if (self.start < other.start) self else other;
|
const a = if (self.start < other.start) self else other;
|
||||||
const b = if (self.start < other.start) other else self;
|
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.
|
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.
|
/// Returns the union of two ranges.
|
||||||
pub fn join(self: Self, other: Self) ?Self {
|
pub fn join(self: Self, other: Self) ?Self {
|
||||||
if (self.intersect(other) == null) return null; // Can't union disjoint ranges.
|
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.
|
// Now guaranteed that they overlap.
|
||||||
const merged = Self{ .start = @min(self.start, other.start), .end = @max(self.end, other.end) };
|
return .{ .start = @min(self.start, other.start), .end = @max(self.end, other.end) };
|
||||||
std.debug.print("= {any}\n", .{merged});
|
|
||||||
return merged;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
const Map = struct {
|
||||||
offset: isize,
|
offset: isize,
|
||||||
source: Range(usize),
|
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 {
|
fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
||||||
var it = util.splitLines(input);
|
var it = util.splitLines(input);
|
||||||
const seed_line = it.next().?;
|
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);
|
var ranges = std.ArrayList(Component).init(alloc);
|
||||||
defer ranges.deinit();
|
defer ranges.deinit();
|
||||||
var lowest_location: usize = std.math.maxInt(usize);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std.debug.print("= seeding {d} =\n", .{seeds.len});
|
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
while (index < seeds.len) : (index += 2) {
|
while (index < seeds.len) : (index += 2) {
|
||||||
try ranges.append(.{
|
try ranges.append(.{
|
||||||
@ -122,7 +91,6 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
|||||||
var current_stage: usize = 0;
|
var current_stage: usize = 0;
|
||||||
while (it.next()) |line| {
|
while (it.next()) |line| {
|
||||||
if (line.len == 0) {
|
if (line.len == 0) {
|
||||||
std.debug.print("== finalise ==\n", .{});
|
|
||||||
for (ranges.items, 0..) |item, index| {
|
for (ranges.items, 0..) |item, index| {
|
||||||
if (item.stage != current_stage) {
|
if (item.stage != current_stage) {
|
||||||
ranges.items[index] = .{ .stage = current_stage, .range = item.range };
|
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:")) {
|
} else if (mem.endsWith(u8, line, "map:")) {
|
||||||
current_stage += 1;
|
current_stage += 1;
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("== stage {d} map {s} ==\n", .{ current_stage, line });
|
|
||||||
const map_line = try util.parseIntsScalar(usize, alloc, line, .{});
|
const map_line = try util.parseIntsScalar(usize, alloc, line, .{});
|
||||||
defer alloc.free(map_line);
|
defer alloc.free(map_line);
|
||||||
const map = Map{
|
const map = Map{
|
||||||
@ -144,40 +111,34 @@ fn solve(alloc: mem.Allocator, input: []const u8) !usize {
|
|||||||
while (i != 0) : (i -= 1) {
|
while (i != 0) : (i -= 1) {
|
||||||
if (ranges.items[i - 1].stage == current_stage) continue;
|
if (ranges.items[i - 1].stage == current_stage) continue;
|
||||||
const item = ranges.swapRemove(i - 1);
|
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| {
|
if (item.range.intersect(.{ .start = 0, .end = map.source.start })) |section| {
|
||||||
// Non-transitioning section.
|
// Non-transitioning section.
|
||||||
std.debug.print("=> s {d}..{d}\n", .{ section.start, section.end });
|
|
||||||
try ranges.append(.{ .stage = item.stage, .range = section });
|
try ranges.append(.{ .stage = item.stage, .range = section });
|
||||||
}
|
}
|
||||||
if (item.range.intersect(map.source)) |section| {
|
if (item.range.intersect(map.source)) |section| {
|
||||||
// Transitioning 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(.{
|
try ranges.append(.{
|
||||||
.stage = current_stage,
|
.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| {
|
if (item.range.intersect(.{ .start = map.source.end, .end = std.math.maxInt(usize) })) |section| {
|
||||||
// Non-transitioning section.
|
// Non-transitioning section.
|
||||||
std.debug.print("=> e {d}..{d}\n", .{ section.start, section.end });
|
|
||||||
try ranges.append(.{ .stage = item.stage, .range = section });
|
try ranges.append(.{ .stage = item.stage, .range = section });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var min_loc: usize = std.math.maxInt(usize);
|
||||||
for (ranges.items) |item| {
|
for (ranges.items) |item| {
|
||||||
std.debug.print("{any}\n", .{item.range});
|
min_loc = @min(min_loc, item.range.start);
|
||||||
lowest_location = @min(lowest_location, item.range.start);
|
|
||||||
}
|
}
|
||||||
|
return min_loc;
|
||||||
return lowest_location;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "silver" {
|
test "silver" {
|
||||||
|
Loading…
Reference in New Issue
Block a user