116 lines
2.8 KiB
Zig
116 lines
2.8 KiB
Zig
const std = @import("std");
|
|
const alloc = std.heap.page_allocator;
|
|
const List = std.ArrayList;
|
|
const OccuranceMap = std.AutoHashMap(Card, u8);
|
|
|
|
pub const Hand = struct {
|
|
cards: [5]Card,
|
|
bid: u64,
|
|
type: HandType,
|
|
};
|
|
|
|
pub const HandType = enum {
|
|
Five,
|
|
Four,
|
|
FullHouse,
|
|
Three,
|
|
TwoPair,
|
|
OnePair,
|
|
HighCard,
|
|
|
|
pub fn as_u8(self: HandType) u8 {
|
|
return switch (self) {
|
|
.Five => 7,
|
|
.Four => 6,
|
|
.FullHouse => 5,
|
|
.Three => 4,
|
|
.TwoPair => 3,
|
|
.OnePair => 2,
|
|
.HighCard => 1,
|
|
};
|
|
}
|
|
};
|
|
|
|
pub const Card = u8;
|
|
|
|
pub fn parse(data: []const u8) !List(Hand) {
|
|
var lines = std.mem.tokenizeScalar(u8, data, '\n');
|
|
|
|
var hands = List(Hand).init(alloc);
|
|
|
|
while (lines.next()) |line| {
|
|
var line_parts = std.mem.tokenizeScalar(u8, line, ' ');
|
|
|
|
const cards_part = line_parts.next().?;
|
|
|
|
var cards: [5]Card = undefined;
|
|
var occurances = OccuranceMap.init(alloc);
|
|
defer occurances.deinit();
|
|
|
|
for (cards_part, 0..) |card, i| {
|
|
const card_num = switch (card) {
|
|
'A' => 14,
|
|
'K' => 13,
|
|
'Q' => 12,
|
|
'J' => 11,
|
|
'T' => 10,
|
|
'2'...'9' => card - 48,
|
|
else => unreachable,
|
|
};
|
|
cards[i] = card_num;
|
|
|
|
if (occurances.get(card_num)) |val| {
|
|
try occurances.put(card_num, val + 1);
|
|
} else {
|
|
try occurances.put(card_num, 1);
|
|
}
|
|
}
|
|
|
|
const hand_type = determine_hand_type(&occurances);
|
|
|
|
const bid_part = line_parts.next().?;
|
|
const bid = try std.fmt.parseInt(u64, bid_part, 10);
|
|
|
|
const hand = .{
|
|
.cards = cards,
|
|
.bid = bid,
|
|
.type = hand_type,
|
|
};
|
|
|
|
try hands.append(hand);
|
|
}
|
|
|
|
return hands;
|
|
}
|
|
|
|
fn determine_hand_type(occurances: *const OccuranceMap) HandType {
|
|
switch (occurances.count()) {
|
|
1 => return HandType.Five,
|
|
2 => {
|
|
var iter = occurances.valueIterator();
|
|
while (iter.next()) |val| {
|
|
switch (val.*) {
|
|
1, 4 => return HandType.Four,
|
|
else => return HandType.FullHouse,
|
|
}
|
|
}
|
|
},
|
|
3 => {
|
|
var iter = occurances.valueIterator();
|
|
while (iter.next()) |val| {
|
|
switch (val.*) {
|
|
3 => return HandType.Three,
|
|
2 => return HandType.TwoPair,
|
|
else => continue,
|
|
}
|
|
unreachable;
|
|
}
|
|
},
|
|
4 => return HandType.OnePair,
|
|
5 => return HandType.HighCard,
|
|
else => unreachable,
|
|
}
|
|
|
|
unreachable;
|
|
}
|