This commit is contained in:
		| @@ -4,18 +4,14 @@ const mem = std.mem; | ||||
|  | ||||
| pub fn main() !void { | ||||
|     const input = @embedFile("data/day07.txt"); | ||||
|     const sln = try solve2(util.gpa, input); | ||||
|     std.debug.print("{d}\n", .{sln.a}); | ||||
|     std.debug.print("{d}\n", .{sln.b}); | ||||
|     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 Solution = struct { | ||||
|     a: usize, | ||||
|     b: usize, | ||||
| }; | ||||
|  | ||||
| const Score = enum(u8) { | ||||
|     fiveKind, | ||||
|     fourKind, | ||||
| @@ -32,13 +28,16 @@ const Hand = struct { | ||||
|     score: Score, | ||||
| }; | ||||
|  | ||||
| fn fixCards(cards: *[5]u8) void { | ||||
| 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' => 0, | ||||
|             'J' => jValue, | ||||
|             'T' => 9, | ||||
|             '2'...'9' => card - '1', | ||||
|             else => unreachable, | ||||
| @@ -52,24 +51,6 @@ fn u8gt(context: void, a: u8, b: u8) bool { | ||||
| } | ||||
|  | ||||
| fn scoreHand(cards: Cards) Score { | ||||
|     var dups: [14]u8 = undefined; | ||||
|     @memset(&dups, 0); | ||||
|     for (cards) |a| { | ||||
|         dups[a] += 1; | ||||
|     } | ||||
|     std.mem.sort(u8, &dups, {}, u8gt); | ||||
|     return switch (dups[0]) { | ||||
|         5 => .fiveKind, | ||||
|         4 => .fourKind, | ||||
|         3 => if (dups[1] == 2) .fullHouse else .threeKind, | ||||
|         2 => if (dups[1] == 2) .twoPair else .onePair, | ||||
|         else => .high, | ||||
|     }; | ||||
| } | ||||
|  | ||||
| const joker = 0; | ||||
|  | ||||
| fn scoreHand2(cards: Cards) Score { | ||||
|     var jokers: usize = 0; | ||||
|     var dups: [14]u8 = undefined; | ||||
|     @memset(&dups, 0); | ||||
| @@ -80,7 +61,7 @@ fn scoreHand2(cards: Cards) Score { | ||||
|             dups[a] += 1; | ||||
|         } | ||||
|     } | ||||
|     std.mem.sort(u8, &dups, {}, u8gt); | ||||
|     mem.sort(u8, &dups, {}, u8gt); | ||||
|     return switch (dups[0] + jokers) { | ||||
|         5 => .fiveKind, | ||||
|         4 => .fourKind, | ||||
| @@ -102,64 +83,28 @@ fn compareHand(context: void, a: Hand, b: Hand) bool { | ||||
|     unreachable; | ||||
| } | ||||
|  | ||||
| fn sortHands(hands: *std.ArrayList(Hand)) !void { | ||||
|     std.mem.sort(Hand, hands.items, {}, compareHand); | ||||
| } | ||||
|  | ||||
| fn solve(alloc: mem.Allocator, input: []const u8) !Solution { | ||||
| 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); | ||||
|         fixCards(&cards, jValue); | ||||
|         const bid = try std.fmt.parseInt(u32, line[6..], 10); | ||||
|         const score = scoreHand(cards); | ||||
|         const hand = Hand{ .cards = cards, .bid = bid, .score = score }; | ||||
|         try hands.append(hand); | ||||
|         try hands.append(.{ .cards = cards, .bid = bid, .score = score }); | ||||
|     } | ||||
|  | ||||
|     // std.debug.print("{any}\n", .{hands.items}); | ||||
|     try sortHands(&hands); | ||||
|     mem.sort(Hand, hands.items, {}, compareHand); | ||||
|  | ||||
|     var partA: usize = 0; | ||||
|     var winnings: u32 = 0; | ||||
|     for (hands.items, 1..) |hand, rank| { | ||||
|         // std.debug.print("{d} * {d}\n", .{ hand.bid, rank }); | ||||
|         partA += hand.bid * rank; | ||||
|         winnings += hand.bid * @as(u32, @intCast(rank)); | ||||
|     } | ||||
|  | ||||
|     return .{ .a = partA, .b = 0 }; | ||||
| } | ||||
|  | ||||
| fn solve2(alloc: mem.Allocator, input: []const u8) !Solution { | ||||
|     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); | ||||
|         const bid = try std.fmt.parseInt(u32, line[6..], 10); | ||||
|         const score = scoreHand2(cards); | ||||
|         const hand = Hand{ .cards = cards, .bid = bid, .score = score }; | ||||
|         try hands.append(hand); | ||||
|     } | ||||
|  | ||||
|     // std.debug.print("{any}\n", .{hands.items}); | ||||
|     try sortHands(&hands); | ||||
|  | ||||
|     var partB: usize = 0; | ||||
|     for (hands.items, 1..) |hand, rank| { | ||||
|         // std.debug.print("{d} * {d}\n", .{ hand.bid, rank }); | ||||
|         partB += hand.bid * rank; | ||||
|     } | ||||
|  | ||||
|     return .{ .a = 0, .b = partB }; | ||||
|     return winnings; | ||||
| } | ||||
|  | ||||
| test "silver" { | ||||
| @@ -170,8 +115,8 @@ test "silver" { | ||||
|         \\KTJJT 220 | ||||
|         \\QQQJA 483 | ||||
|     ; | ||||
|     const sln = try solve(std.testing.allocator, input); | ||||
|     try std.testing.expectEqual(@as(usize, 6440), sln.a); | ||||
|     const sln = try solve(std.testing.allocator, input, jack); | ||||
|     try std.testing.expectEqual(@as(usize, 6440), sln); | ||||
| } | ||||
|  | ||||
| test "gold" { | ||||
| @@ -182,6 +127,6 @@ test "gold" { | ||||
|         \\KTJJT 220 | ||||
|         \\QQQJA 483 | ||||
|     ; | ||||
|     const sln = try solve2(std.testing.allocator, input); | ||||
|     try std.testing.expectEqual(@as(usize, 5905), sln.b); | ||||
|     const sln = try solve(std.testing.allocator, input, joker); | ||||
|     try std.testing.expectEqual(@as(usize, 5905), sln); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user