Day 5;
This commit is contained in:
1
AdventOfCode2023/.gitignore
vendored
1
AdventOfCode2023/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
zig-cache
|
zig-cache
|
||||||
zig-out
|
zig-out
|
||||||
|
input.txt
|
||||||
|
195
AdventOfCode2023/src/day5/day5.zig
Normal file
195
AdventOfCode2023/src/day5/day5.zig
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const print = std.debug.print;
|
||||||
|
const ArrayList = std.ArrayList;
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
|
||||||
|
const Range = struct {
|
||||||
|
sourceStart: usize,
|
||||||
|
destinationStart: usize,
|
||||||
|
rangeLength: usize,
|
||||||
|
|
||||||
|
pub fn fits(self: Range, input: usize) bool {
|
||||||
|
return input >= self.sourceStart and input < self.sourceStart + self.rangeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute(self: Range, input: usize) usize {
|
||||||
|
if (self.fits(input)) {
|
||||||
|
var distanceFromStart = input - self.sourceStart;
|
||||||
|
return self.destinationStart + distanceFromStart;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prettyPrint(self: Range) void {
|
||||||
|
print("Start: {} | Destination Start: {} | Length: {}\n", .{ self.sourceStart, self.destinationStart, self.rangeLength });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "Test range" {
|
||||||
|
var range = Range{ .sourceStart = 50, .destinationStart = 98, .rangeLength = 2 };
|
||||||
|
try expect(range.compute(49) == 49);
|
||||||
|
try expect(range.compute(50) == 98);
|
||||||
|
try expect(range.compute(51) == 99);
|
||||||
|
try expect(range.compute(52) == 52);
|
||||||
|
|
||||||
|
try expect(range.fits(51));
|
||||||
|
|
||||||
|
var otherRange = Range{ .sourceStart = 18, .destinationStart = 25, .rangeLength = 70 };
|
||||||
|
try expect(otherRange.fits(40));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getSeeds(input: [][]const u8) ![]usize {
|
||||||
|
var allocator = std.heap.page_allocator;
|
||||||
|
|
||||||
|
var seedsLine = input[0][7..];
|
||||||
|
var seedNumbers = std.mem.tokenizeSequence(u8, seedsLine, " ");
|
||||||
|
var seedsList = ArrayList(usize).init(allocator);
|
||||||
|
defer seedsList.deinit();
|
||||||
|
|
||||||
|
while (seedNumbers.next()) |num| {
|
||||||
|
try seedsList.append(try std.fmt.parseInt(usize, num, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
var seeds = try seedsList.toOwnedSlice();
|
||||||
|
return seeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseRange(line: []const u8, reverse: bool) !Range {
|
||||||
|
var seedNumbers = std.mem.tokenizeSequence(u8, line, " ");
|
||||||
|
var destinationStart = try std.fmt.parseInt(usize, seedNumbers.next().?, 10);
|
||||||
|
var sourceStart = try std.fmt.parseInt(usize, seedNumbers.next().?, 10);
|
||||||
|
var rangeLength = try std.fmt.parseInt(usize, seedNumbers.next().?, 10);
|
||||||
|
if (reverse) {
|
||||||
|
return Range{ .sourceStart = destinationStart, .destinationStart = sourceStart, .rangeLength = rangeLength };
|
||||||
|
}
|
||||||
|
return Range{ .sourceStart = sourceStart, .destinationStart = destinationStart, .rangeLength = rangeLength };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn traverseMaps(maps: [7]*ArrayList(Range), input: usize) usize {
|
||||||
|
var mappedValue = input;
|
||||||
|
for (maps) |map| {
|
||||||
|
// print("Mapped value: {}\n", .{mappedValue});
|
||||||
|
for (map.*.items) |range| {
|
||||||
|
if (range.fits(mappedValue)) {
|
||||||
|
mappedValue = range.compute(mappedValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mappedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn solve(input: [][]const u8) !void {
|
||||||
|
var allocator = std.heap.page_allocator;
|
||||||
|
|
||||||
|
var seeds = try getSeeds(input);
|
||||||
|
|
||||||
|
var seedToSoil = ArrayList(Range).init(allocator);
|
||||||
|
var soilToFert = ArrayList(Range).init(allocator);
|
||||||
|
var fertToWater = ArrayList(Range).init(allocator);
|
||||||
|
var waterToLight = ArrayList(Range).init(allocator);
|
||||||
|
var lightToTemp = ArrayList(Range).init(allocator);
|
||||||
|
var tempToHumid = ArrayList(Range).init(allocator);
|
||||||
|
var humidToLocation = ArrayList(Range).init(allocator);
|
||||||
|
|
||||||
|
var locationToHumid = ArrayList(Range).init(allocator);
|
||||||
|
var humidToTemp = ArrayList(Range).init(allocator);
|
||||||
|
var tempToLight = ArrayList(Range).init(allocator);
|
||||||
|
var lightToWater = ArrayList(Range).init(allocator);
|
||||||
|
var waterToFert = ArrayList(Range).init(allocator);
|
||||||
|
var fertToSoil = ArrayList(Range).init(allocator);
|
||||||
|
var soilToSeed = ArrayList(Range).init(allocator);
|
||||||
|
|
||||||
|
var maps = [7]*ArrayList(Range){ &seedToSoil, &soilToFert, &fertToWater, &waterToLight, &lightToTemp, &tempToHumid, &humidToLocation };
|
||||||
|
|
||||||
|
var reverseMaps = [7]*ArrayList(Range){ &locationToHumid, &humidToTemp, &tempToLight, &lightToWater, &waterToFert, &fertToSoil, &soilToSeed };
|
||||||
|
|
||||||
|
defer seedToSoil.deinit();
|
||||||
|
defer soilToFert.deinit();
|
||||||
|
defer fertToWater.deinit();
|
||||||
|
defer waterToLight.deinit();
|
||||||
|
defer lightToTemp.deinit();
|
||||||
|
defer tempToHumid.deinit();
|
||||||
|
defer humidToLocation.deinit();
|
||||||
|
|
||||||
|
defer locationToHumid.deinit();
|
||||||
|
defer humidToTemp.deinit();
|
||||||
|
defer tempToLight.deinit();
|
||||||
|
defer lightToWater.deinit();
|
||||||
|
defer waterToFert.deinit();
|
||||||
|
defer fertToSoil.deinit();
|
||||||
|
defer soilToSeed.deinit();
|
||||||
|
|
||||||
|
var index: usize = 2;
|
||||||
|
var stages: usize = 0;
|
||||||
|
|
||||||
|
while (index < input.len) {
|
||||||
|
var line = input[index];
|
||||||
|
|
||||||
|
if (line[0] < '0' or line[0] > '9') {
|
||||||
|
stages += 1;
|
||||||
|
index += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var range = try parseRange(line, false);
|
||||||
|
var reverseRange = try parseRange(line, true);
|
||||||
|
|
||||||
|
if (stages == 0) {
|
||||||
|
try seedToSoil.append(range);
|
||||||
|
try soilToSeed.append(reverseRange);
|
||||||
|
} else if (stages == 1) {
|
||||||
|
try soilToFert.append(range);
|
||||||
|
try fertToSoil.append(reverseRange);
|
||||||
|
} else if (stages == 2) {
|
||||||
|
try fertToWater.append(range);
|
||||||
|
try waterToFert.append(reverseRange);
|
||||||
|
} else if (stages == 3) {
|
||||||
|
try waterToLight.append(range);
|
||||||
|
try lightToWater.append(reverseRange);
|
||||||
|
} else if (stages == 4) {
|
||||||
|
try lightToTemp.append(range);
|
||||||
|
try tempToLight.append(reverseRange);
|
||||||
|
} else if (stages == 5) {
|
||||||
|
try tempToHumid.append(range);
|
||||||
|
try humidToTemp.append(reverseRange);
|
||||||
|
} else if (stages == 6) {
|
||||||
|
try humidToLocation.append(range);
|
||||||
|
try locationToHumid.append(reverseRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lowest: usize = 999999999999;
|
||||||
|
var lowestSeed: usize = 0;
|
||||||
|
|
||||||
|
for (seeds) |seed| {
|
||||||
|
var location = traverseMaps(maps, seed);
|
||||||
|
if (location < lowest) {
|
||||||
|
lowest = location;
|
||||||
|
lowestSeed = seed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Part 1: {} | Seed: {}\n", .{ lowest, lowestSeed });
|
||||||
|
|
||||||
|
var part2: usize = 1;
|
||||||
|
outerLoop: while (true) {
|
||||||
|
var seed = traverseMaps(reverseMaps, part2);
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i <= seeds.len / 2) {
|
||||||
|
if (seeds[i] <= seed and seeds[i] + seeds[i + 1] > seed) {
|
||||||
|
break :outerLoop;
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part2 % 10_000_000 == 0) {
|
||||||
|
print("Counting: {}\n", .{part2});
|
||||||
|
}
|
||||||
|
|
||||||
|
part2 += 1;
|
||||||
|
}
|
||||||
|
print("Part 2: {}\n", .{part2});
|
||||||
|
}
|
@ -2,13 +2,14 @@ const std = @import("std");
|
|||||||
// const day1 = @import("./day1/day1.zig");
|
// const day1 = @import("./day1/day1.zig");
|
||||||
// const day2 = @import("./day2/day2.zig");
|
// const day2 = @import("./day2/day2.zig");
|
||||||
// const day3 = @import("./day3/day3.zig");
|
// const day3 = @import("./day3/day3.zig");
|
||||||
const day4 = @import("./day4/day4.zig");
|
// const day4 = @import("./day4/day4.zig");
|
||||||
|
const day5 = @import("./day5/day5.zig");
|
||||||
const utils = @import("utils.zig");
|
const utils = @import("utils.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const allocator = std.heap.page_allocator;
|
const allocator = std.heap.page_allocator;
|
||||||
var input = try utils.getInput("./src/day4/input.txt", allocator);
|
var input = try utils.getInput("./src/day5/input.txt", allocator);
|
||||||
defer allocator.free(input);
|
defer allocator.free(input);
|
||||||
|
|
||||||
try day4.solve(input);
|
try day5.solve(input);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user