1
0

Compare commits

...

3 Commits

Author SHA1 Message Date
300ceb885f
wash day07
Some checks failed
Build and test / test (push) Failing after 2m40s
2023-12-07 17:19:51 +11:00
221cad1136
unwashed day07 2023-12-07 17:10:52 +11:00
05ffa1e7c1
day07 part1 2023-12-07 17:05:56 +11:00

132
src/day07.zig Normal file
View File

@ -0,0 +1,132 @@
const std = @import("std");
const util = @import("util.zig");
const mem = std.mem;
pub fn main() !void {
const input = @embedFile("data/day07.txt");
const part1 = try solve(util.gpa, input, jack);
const part2 = try solve(util.gpa, input, joker);
std.debug.print("{d}\n", .{part1});
std.debug.print("{d}\n", .{part2});
}
const Cards = [5]u8;
const Score = enum(u8) {
fiveKind,
fourKind,
fullHouse,
threeKind,
twoPair,
onePair,
high,
};
const Hand = struct {
cards: [5]u8,
bid: u32,
score: Score,
};
const jack = 10;
const joker = 0;
fn fixCards(cards: *[5]u8, jValue: u8) void {
for (cards, 0..) |card, i| {
cards[i] = switch (card) {
'A' => 13,
'K' => 12,
'Q' => 11,
'J' => jValue,
'T' => 9,
'2'...'9' => card - '1',
else => unreachable,
};
}
}
fn u8gt(context: void, a: u8, b: u8) bool {
_ = context;
return a > b;
}
fn scoreHand(cards: Cards) Score {
var jokers: usize = 0;
var dups: [14]u8 = undefined;
@memset(&dups, 0);
for (cards) |a| {
if (a == joker) {
jokers += 1;
} else {
dups[a] += 1;
}
}
mem.sort(u8, &dups, {}, u8gt);
return switch (dups[0] + jokers) {
5 => .fiveKind,
4 => .fourKind,
3 => if (dups[1] == 2) .fullHouse else .threeKind,
2 => if (dups[1] == 2) .twoPair else .onePair,
else => .high,
};
}
fn compareHand(context: void, a: Hand, b: Hand) bool {
_ = context;
if (a.score != b.score) {
return @intFromEnum(a.score) > @intFromEnum(b.score);
} else {
for (a.cards, b.cards) |cardA, cardB| {
if (cardA != cardB) return cardA < cardB;
}
}
unreachable;
}
fn solve(alloc: mem.Allocator, input: []const u8, jValue: u8) !u32 {
var hands = try std.ArrayList(Hand).initCapacity(alloc, 1001);
defer hands.deinit();
var it = util.splitLines(input);
while (it.next()) |line| {
if (line.len == 0) continue;
var cards = line[0..5].*;
fixCards(&cards, jValue);
const bid = try std.fmt.parseInt(u32, line[6..], 10);
const score = scoreHand(cards);
try hands.append(.{ .cards = cards, .bid = bid, .score = score });
}
mem.sort(Hand, hands.items, {}, compareHand);
var winnings: u32 = 0;
for (hands.items, 1..) |hand, rank| {
winnings += hand.bid * @as(u32, @intCast(rank));
}
return winnings;
}
test "silver" {
const input =
\\32T3K 765
\\T55J5 684
\\KK677 28
\\KTJJT 220
\\QQQJA 483
;
const sln = try solve(std.testing.allocator, input, jack);
try std.testing.expectEqual(@as(usize, 6440), sln);
}
test "gold" {
const input =
\\32T3K 765
\\T55J5 684
\\KK677 28
\\KTJJT 220
\\QQQJA 483
;
const sln = try solve(std.testing.allocator, input, joker);
try std.testing.expectEqual(@as(usize, 5905), sln);
}