const std = @import("std");
const path = "../data/day24/input.txt";
const input_counter = 14; // number of instruction blocks
const input_length = 18; // items in each instruction block
const offset0 = 5;
const offset1 = 15;
const PairType = i9;
const Pair = [2]PairType;
const Pairs = [input_counter]Pair;
pub fn main() !void {
var timer = try std.time.Timer.start();
const ret = try second();
const t = timer.lap() / 1000;
try std.testing.expectEqual(@as(usize, 93185111127911), ret);
std.debug.print("Day 24b result: {d} \t\ttime: {d}µs\n", .{ ret, t });
}
pub fn second() !usize {
const start = 1;
const pairs = try parseInput();
const allocator = std.testing.allocator;
var stack = std.ArrayList(Pair).init(allocator);
defer stack.deinit();
var ret: usize = 0;
var i: usize = 0;
while (i < input_counter) : (i += 1) {
if (pairs[i][0] > 0) {
try stack.append(Pair{ pairs[i][1], @intCast(PairType, i) });
} else {
const p = stack.pop();
var add: PairType = start;
while (add + p[0] + pairs[i][0] < start) {
add += 1;
}
ret += @intCast(usize, add) *
try std.math.powi(usize, 10, @intCast(usize, input_counter - 1 - p[1]));
ret += @intCast(usize, (add + p[0] + pairs[i][0])) *
try std.math.powi(usize, 10, input_counter - 1 - i);
}
}
return ret;
}
fn parseInput() !Pairs {
const input = @embedFile(path);
var line = std.mem.split(u8, input, "\n");
var ret: Pairs = undefined;
var line_counter: usize = 0;
var item_counter: usize = 0;
while (line.next()) |l| : (line_counter += 1) {
if (line_counter == input_length * item_counter + offset0) {
var token = std.mem.tokenize(u8, l, " ");
_ = token.next();
_ = token.next();
ret[item_counter][0] = try std.fmt.parseInt(PairType, token.next().?, 10);
}
if (line_counter == input_length * item_counter + offset1) {
var token = std.mem.tokenize(u8, l, " ");
_ = token.next();
_ = token.next();
ret[item_counter][1] = try std.fmt.parseInt(PairType, token.next().?, 10);
item_counter += 1;
}
}
return ret;
}
test "day24b" {
try std.testing.expectEqual(@as(usize, 93185111127911), try second());
}