77 lines
2.1 KiB
Zig
77 lines
2.1 KiB
Zig
const std = @import("std");
|
|
const Io = std.Io;
|
|
|
|
const shared = @import("shared.zig");
|
|
const print = shared.print;
|
|
|
|
pub fn insertIfNotSmallest(allocator: std.mem.Allocator, list: *std.ArrayList(Result), value: u8, index: usize) !void {
|
|
for (list.items) |result| {
|
|
if (value > result.value) {
|
|
try list.append(allocator, .{ .index = index, .value = value });
|
|
break;
|
|
}
|
|
}
|
|
|
|
std.mem.sort(Result, list.items, {}, Result.compareValues);
|
|
}
|
|
|
|
const Result = struct {
|
|
index: usize,
|
|
value: u8,
|
|
|
|
pub fn compareValues(_: void, lhs: @This(), rhs: @This()) bool {
|
|
return lhs.value > rhs.value;
|
|
}
|
|
|
|
pub fn compareIndex(_: void, lhs: @This(), rhs: @This()) bool {
|
|
return lhs.index < rhs.index;
|
|
}
|
|
};
|
|
|
|
pub fn selectNLargest(comptime N: usize, allocator: std.mem.Allocator, line: []const u8) ![N]usize {
|
|
var list: std.ArrayList(Result) = .empty;
|
|
try list.appendNTimes(allocator, .{ .index = line.len, .value = 0 }, N);
|
|
defer list.deinit(allocator);
|
|
|
|
for (line, 0..) |x, i| {
|
|
try insertIfNotSmallest(allocator, &list, x, i);
|
|
|
|
while (list.items.len > 2) {
|
|
_ = list.pop();
|
|
}
|
|
}
|
|
|
|
std.mem.sort(Result, list.items, {}, Result.compareIndex);
|
|
|
|
var rv: [N]usize = .{ line.len, line.len };
|
|
for (0..N) |i| {
|
|
rv[i] = list.items[i].index;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
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 digits: std.ArrayList(u8) = .empty;
|
|
defer digits.deinit(allocator);
|
|
|
|
while (lineIter.next()) |l| {
|
|
const line = shared.trim(l);
|
|
const x = try selectNLargest(2, allocator, line);
|
|
digits.clearRetainingCapacity();
|
|
for (0..x.len) |i| {
|
|
try digits.append(allocator, line[x[i]]);
|
|
}
|
|
print("{s}", .{digits.items});
|
|
part1 += try std.fmt.parseInt(i64, digits.items, 10);
|
|
}
|
|
|
|
print("part1 {d}", .{part1});
|
|
}
|