123 lines
3.5 KiB
Zig
123 lines
3.5 KiB
Zig
const std = @import("std");
|
|
const Io = std.Io;
|
|
|
|
const shared = @import("shared.zig");
|
|
const print = shared.print;
|
|
|
|
// for each value,
|
|
// build a list of all possible subvalues it can combine with,
|
|
// trim to largest for each value
|
|
|
|
// limited single loop for part 1
|
|
pub fn findLargest(line: []const u8, charsLeft: usize) usize {
|
|
var largest: u8 = 0;
|
|
var index: usize = 0;
|
|
|
|
for (line, 0..) |v, i| {
|
|
if (v > largest and line.len - i > charsLeft) {
|
|
// print("{d}", .{line[i] - '0'});
|
|
index = i;
|
|
largest = line[i];
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
const RecursiveFind = struct {
|
|
line: []const u8,
|
|
arena: std.heap.ArenaAllocator,
|
|
count: usize,
|
|
backing: std.mem.Allocator,
|
|
output: std.ArrayList(usize) = .empty,
|
|
|
|
pub fn init(allocator: std.mem.Allocator, line: []const u8, count: usize) @This() {
|
|
return .{
|
|
.line = line,
|
|
.count = count,
|
|
.backing = allocator,
|
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *@This()) void {
|
|
self.arena.deinit();
|
|
}
|
|
|
|
pub fn toDigits(self: *@This(), allocator: std.mem.Allocator, out: *std.ArrayList(u8)) !void {
|
|
for (self.output.items) |i| {
|
|
try out.append(allocator, self.line[i]);
|
|
}
|
|
}
|
|
|
|
// RecursiveFindNextLargestDigit
|
|
pub fn rflnd(self: *@This(), offset: usize) void {
|
|
const charsLeft = self.count - self.output.items.len;
|
|
if (charsLeft == 0 or offset > self.line.len)
|
|
return;
|
|
|
|
const allocator = self.arena.allocator();
|
|
const subline = self.line[offset..self.line.len];
|
|
|
|
const index = findLargest(subline, charsLeft - 1) + offset;
|
|
|
|
if (index == self.line.len)
|
|
return;
|
|
|
|
self.output.append(allocator, index) catch unreachable;
|
|
|
|
rflnd(self, index + 1);
|
|
}
|
|
};
|
|
|
|
pub fn main(init: std.process.Init) !void {
|
|
try shared.sharedInit(init);
|
|
const allocator: std.mem.Allocator = init.arena.allocator();
|
|
const bytes = shared.loadBytesArg(allocator);
|
|
|
|
var lineIter = std.mem.tokenizeScalar(u8, bytes, '\n');
|
|
|
|
var part1: i64 = 0;
|
|
var part2: i64 = 0;
|
|
var digits: std.ArrayList(u8) = .empty;
|
|
defer digits.deinit(allocator);
|
|
|
|
while (lineIter.next()) |l| {
|
|
const line = shared.trim(l);
|
|
var find = RecursiveFind.init(allocator, line, 2);
|
|
|
|
find.rflnd(0);
|
|
defer find.deinit();
|
|
digits.clearRetainingCapacity();
|
|
try find.toDigits(allocator, &digits);
|
|
part1 += try std.fmt.parseInt(i64, digits.items, 10);
|
|
|
|
var find2 = RecursiveFind.init(allocator, line, 12);
|
|
defer find2.deinit();
|
|
find2.rflnd(0);
|
|
|
|
digits.clearRetainingCapacity();
|
|
try find2.toDigits(allocator, &digits);
|
|
part2 += try std.fmt.parseInt(i64, digits.items, 10);
|
|
}
|
|
|
|
print("part1 {d}", .{part1});
|
|
print("part2 {d}", .{part2});
|
|
}
|
|
//while (lineIter.next()) |l| {
|
|
// const line = shared.trim(l);
|
|
// lineLargest = 0;
|
|
// for (line[0 .. line.len - 1], 0..) |c, i| {
|
|
// const offset = findLargest(line[i + 1 .. line.len]) + i + 1;
|
|
// digits.clearRetainingCapacity();
|
|
// try digits.append(allocator, c);
|
|
// try digits.append(allocator, line[offset]);
|
|
// const x = try std.fmt.parseInt(i64, digits.items, 10);
|
|
// if (x > lineLargest) {
|
|
// print("{d}", .{x});
|
|
// lineLargest = x;
|
|
// }
|
|
// }
|
|
// part1 += lineLargest;
|
|
//}
|