const std = @import("std");
const INPUT = "394618527";
const Str = []const u8;
pub fn first(allocator: ?std.mem.Allocator) anyerror!usize {
var cc = try parseInput(allocator.?, INPUT);
defer {
cc.cups.deinit();
}
var round: usize = 0;
while (round < 100) : (round += 1) {
// std.debug.print("{d} {any}\n", .{ cc.current, cc.cups.items });
try cc.move(allocator.?);
}
var ret: usize = 0;
const one = std.mem.indexOf(CupType, cc.cups.items, &[_]CupType{1}).?;
var idx: usize = 0;
while (idx < 8) : (idx += 1) {
ret += cc.cups.items[(one + idx + 1) % cc.cups.items.len] *
try std.math.powi(usize, 10, cc.cups.items.len - idx - 2);
}
return ret;
}
pub fn second(allocator: ?std.mem.Allocator) anyerror!usize {
_ = allocator;
return 0;
}
const CupType = u4;
const Cups = std.ArrayList(CupType);
const CrabCups = struct {
cups: Cups = undefined,
fn move(self: *@This(), allocator: std.mem.Allocator) !void {
const cup1 = self.cups.orderedRemove(1);
const cup2 = self.cups.orderedRemove(1);
const cup3 = self.cups.orderedRemove(1);
// std.debug.print("pick up: {d} {d} {d}\n", .{ cup1, cup2, cup3 });
const destination = blk: {
var dest: CupType = self.cups.items[0];
while (true) : (dest -= 1) {
if (dest == 0) dest = 9;
if (dest != self.cups.items[0] and dest != cup1 and dest != cup2 and dest != cup3) {
break;
}
}
break :blk dest;
};
// std.debug.print("destination: {}\n", .{destination});
const dest_index = std.mem.indexOf(CupType, self.cups.items, &[_]CupType{destination}).?;
try self.cups.insertSlice((dest_index + 1) % 9, &[_]CupType{ cup1, cup2, cup3 });
var next = try Cups.initCapacity(allocator, self.cups.items.len);
for ([_]usize{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }) |offset| {
next.appendAssumeCapacity(self.cups.items[offset % self.cups.items.len]);
}
self.cups.deinit();
self.cups = next;
}
};
fn parseInput(allocator: std.mem.Allocator, input: Str) anyerror!CrabCups {
var ret: CrabCups = undefined;
ret.cups = try std.ArrayList(CupType).initCapacity(allocator, 9);
for (input) |_, idx| {
const cup = try std.fmt.parseUnsigned(CupType, input[idx .. idx + 1], 10);
ret.cups.appendAssumeCapacity(cup);
}
return ret;
}
test "day23a" {
try std.testing.expectEqual(@as(usize, 78569234), try first(std.testing.allocator));
}
test "day23b" {
try std.testing.expectEqual(@as(usize, 0), try second(std.testing.allocator));
}
const test_input = "389125467";