this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

part 2!

+158 -11
+114 -5
2023/day07/part2.ts
··· 1 + export function answer(input: string): number { 2 + const handsAndBids = input.split("\n").map(parseHand); 3 + 4 + handsAndBids.sort(([handA], [handB]) => { 5 + const [typeA, typeB] = [handType(handA), handType(handB)]; 6 + if (typeA !== typeB) { 7 + return HAND_TYPES.indexOf(typeA) > HAND_TYPES.indexOf(typeB) ? 1 : -1; 8 + } else { 9 + for (let i = 0; i < handA.length; i++) { 10 + if (handA[i] !== handB[i]) { 11 + return CARDS.indexOf(handA[i]) > CARDS.indexOf(handB[i]) ? 1 : -1; 12 + } 13 + } 14 + } 15 + throw `hands are the same!: ${handA} ${handB}`; 16 + }); 17 + 18 + return handsAndBids.reduce( 19 + (sum, [_hand, bid], rank) => sum + bid * (rank + 1), 20 + 0, 21 + ); 22 + } 23 + 24 + const CARDS = "J23456789TQKA"; 25 + const HAND_TYPES = [ 26 + "high card", 27 + "1 pair", 28 + "2 pair", 29 + "3 of a kind", 30 + "full house", 31 + "4 of a kind", 32 + "5 of a kind", 33 + ]; 34 + 35 + function parseHand(l: string): [string, number] { 36 + const [hand, bidStr] = l.split(" "); 37 + return [hand, parseInt(bidStr)]; 38 + } 39 + 40 + const cardCounts = (hand: string[]) => ({ 41 + "2": hand.filter((c) => c === "2").length, 42 + "3": hand.filter((c) => c === "3").length, 43 + "4": hand.filter((c) => c === "4").length, 44 + "5": hand.filter((c) => c === "5").length, 45 + "6": hand.filter((c) => c === "6").length, 46 + "7": hand.filter((c) => c === "7").length, 47 + "8": hand.filter((c) => c === "8").length, 48 + "9": hand.filter((c) => c === "9").length, 49 + T: hand.filter((c) => c === "T").length, 50 + J: hand.filter((c) => c === "J").length, 51 + Q: hand.filter((c) => c === "Q").length, 52 + K: hand.filter((c) => c === "K").length, 53 + A: hand.filter((c) => c === "A").length, 54 + }); 55 + 56 + const isFiveOfAKind = (cards: string[]): boolean => new Set(cards).size === 1; 57 + 58 + const isFourOfAKind = (cards: string[]): boolean => { 59 + const uniqueCards = new Set(cards); 60 + return ( 61 + uniqueCards.size >= 2 && 62 + [...uniqueCards].some((c) => cards.filter((cc) => cc === c).length === 4) 63 + ); 64 + }; 65 + 66 + const isThreeOfAKind = (cards: string[]): boolean => { 67 + const uniqueCards = new Set(cards); 68 + return ( 69 + uniqueCards.size >= 2 && 70 + [...uniqueCards].some((c) => cards.filter((cc) => cc === c).length === 3) 71 + ); 72 + }; 73 + 74 + const isFullHouse = (cards: string[]): boolean => { 75 + const uniqueCards = new Set(cards); 76 + return ( 77 + uniqueCards.size === 2 && 78 + Object.values(cardCounts(cards)).filter((c) => c > 1).length === 2 79 + ); 80 + }; 81 + 82 + const pairs = (cards: string[]): number => 83 + Object.values(cardCounts(cards)).filter((c) => c === 2).length; 84 + const isTwoPair = (cards: string[]): boolean => pairs(cards) === 2; 85 + const isOnePair = (cards: string[]): boolean => pairs(cards) === 1; 86 + 87 + function handType(hand: string): string { 88 + function possibleHandTypes(h: string[], typesSoFar: string[] = []): string[] { 89 + if (h.includes("J")) { 90 + return [ 91 + ...typesSoFar, 92 + ...CARDS.slice(1) 93 + .split("") 94 + .map((c) => 95 + possibleHandTypes(h.join("").replace("J", c).split(""), typesSoFar), 96 + ) 97 + .flat(), 98 + ]; 99 + } 100 + if (isFiveOfAKind(h)) return [...typesSoFar, "5 of a kind"]; 101 + if (isFourOfAKind(h)) return [...typesSoFar, "4 of a kind"]; 102 + if (isFullHouse(h)) return [...typesSoFar, "full house"]; 103 + if (isThreeOfAKind(h)) return [...typesSoFar, "3 of a kind"]; 104 + if (isTwoPair(h)) return [...typesSoFar, "2 pair"]; 105 + if (isOnePair(h)) return [...typesSoFar, "1 pair"]; 106 + return [...typesSoFar, "high card"]; 107 + } 108 + 109 + const possibleTypes = [...new Set(possibleHandTypes(hand.split("")))].sort( 110 + (a, b) => (HAND_TYPES.indexOf(a) > HAND_TYPES.indexOf(b) ? -1 : 1), 111 + ); 112 + return possibleTypes[0]; 113 + } 114 + 1 115 if (import.meta.main) { 2 116 const input = ( 3 117 await Deno.readFile("input").then((bytes) => ··· 6 120 ).trim(); 7 121 console.log(answer(input)); 8 122 } 9 - 10 - export function answer(input: string): number { 11 - console.log(input); 12 - return 42; 13 - }
+34 -2
2023/day07/puzzle.md
··· 58 58 59 59 Find the rank of every hand in your set. *What are the total winnings?* 60 60 61 - To begin, [get your puzzle input](7/input). 61 + Your puzzle answer was `251136060`. 62 + 63 + The first half of this puzzle is complete! It provides one gold star: \* 64 + 65 + \--- Part Two --- 66 + ---------- 67 + 68 + To make things a little more interesting, the Elf introduces one additional rule. Now, `J` cards are [jokers](https://en.wikipedia.org/wiki/Joker_(playing_card)) - wildcards that can act like whatever card would make the hand the strongest type possible. 69 + 70 + To balance this, *`J` cards are now the weakest* individual cards, weaker even than `2`. The other cards stay in the same order: `A`, `K`, `Q`, `T`, `9`, `8`, `7`, `6`, `5`, `4`, `3`, `2`, `J`. 71 + 72 + `J` cards can pretend to be whatever card is best for the purpose of determining hand type; for example, `QJJQ2` is now considered *four of a kind*. However, for the purpose of breaking ties between two hands of the same type, `J` is always treated as `J`, not the card it's pretending to be: `JKKK2` is weaker than `QQQQ2` because `J` is weaker than `Q`. 73 + 74 + Now, the above example goes very differently: 75 + 76 + ``` 77 + 32T3K 765 78 + T55J5 684 79 + KK677 28 80 + KTJJT 220 81 + QQQJA 483 82 + 83 + ``` 84 + 85 + * `32T3K` is still the only *one pair*; it doesn't contain any jokers, so its strength doesn't increase. 86 + * `KK677` is now the only *two pair*, making it the second-weakest hand. 87 + * `T55J5`, `KTJJT`, and `QQQJA` are now all *four of a kind*! `T55J5` gets rank 3, `QQQJA` gets rank 4, and `KTJJT` gets rank 5. 88 + 89 + With the new joker rule, the total winnings in this example are `*5905*`. 90 + 91 + Using the new joker rule, find the rank of every hand in your set. *What are the new total winnings?* 62 92 63 93 Answer: 64 94 65 - You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22Camel+Cards%22+%2D+Day+7+%2D+Advent+of+Code+2023&url=https%3A%2F%2Fadventofcode%2Ecom%2F2023%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle. 95 + Although it hasn't changed, you can still [get your puzzle input](7/input). 96 + 97 + You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=I%27ve+completed+Part+One+of+%22Camel+Cards%22+%2D+Day+7+%2D+Advent+of+Code+2023&url=https%3A%2F%2Fadventofcode%2Ecom%2F2023%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle.
+10 -4
2023/day07/test.ts
··· 13 13 assertEquals(p1.answer(examples), 6440); 14 14 }); 15 15 16 - // Deno.test("part2", () => { 17 - // const examples = ["abc", "def"].join("\n"); 18 - // assertEquals(p2.answer(examples), 42); 19 - // }); 16 + Deno.test("part2", () => { 17 + const examples = [ 18 + "32T3K 765", 19 + "T55J5 684", 20 + "KK677 28", 21 + "KTJJT 220", 22 + "QQQJA 483", 23 + ].join("\n"); 24 + assertEquals(p2.answer(examples), 5905); 25 + });