Xah Talk Show 2024-01-26 Ep534 Advent of Code, Day 7, Live Coding in WolframLang
- Timestamp
- 04:09 reading the problem
- 19:23 start coding
- 20:58 analize the problem
- 26:48 analize hand ranking
- 30:56 WolframLang SortBy
- 37:43 find repetitions in string
- 42:26 CharacterCounts
- 01:00:46 download WolframLang
- 1:20:04 done function for sorting hand type
- 1:26:33 emacs pixel scroll
- 01:39:45 5 min break
- 01:52:23 function for card ordering
- 01:59:23 emacs keyboard macro
- 02:19:31 answer for sample input
- 02:23:24 answer for user input
problem description
given text line this
32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483
for each line, the first part is card hands, second part is bid.
The card hands is a sequence of the following characters (listed from strongest to weakest)
A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2
you need to order the lines by their strength, each hand are ranked this way, from strongest to weakest
- Five of a kind, where all five cards have the same label: AAAAA
- Four of a kind, where four cards have the same label and one card has a different label: AA8AA
- Full house, where three cards have the same label, and the remaining two cards share a different label: 23332
- Three of a kind, where three cards have the same label, and the remaining two cards are each different from any other card in the hand: TTT98
- Two pair, where two cards share one label, two other cards share a second label, and the remaining card has a third label: 23432
- One pair, where two cards share one label, and the other three cards have a different label from the pair and each other: A23A4
- High card, where all cards' labels are distinct: 23456
when 2 hands have the same rank, you break the tie by strength of first char, if tie, by second char, and so on.
After you order them, from weakest to strongest, each line's index indicate their rank. First line has rank 1, second line has rank 2, etc.
multiply each rank by its bid. and sum them up.
For example, answer for the given input is 6440.
(* Advent of Code 2023, Day 7, part 1, Solution in WolframLang *) input = "32T3K 765 T55J5 684 KK677 28 KTJJT 220 QQQJA 483"; (* input = "32T3K 765 T55J5 684 KK677 28 KTJJT 220 KKKJA 483 AAAJ4 483 QQQJA 483"; *) input = ReadString[ "c:/Users/xah/web/xahlee_info/talk_show/i/advent_of_code_2023_day_7_input.txt" ]; sortTable = Association[ { "A" -> 14, "K" -> 13, "Q" -> 12, "J" -> 11, "T" -> 10, "9" -> 9, "8" -> 8, "7" -> 7, "6" -> 6, "5" -> 5, "4" -> 4, "3" -> 3, "2" -> 2 } ]; listOfOrderedHands = SortBy[ StringSplit[ input, "\n" ], {Function@ PadRight[ReverseSort@ Values@ CharacterCounts@ StringSplit[ # ][[1]], 5, 0], Function@ Lookup[ sortTable, (Characters@ StringSplit[ # ][[1]])] } ]; Total@ MapIndexed[ Function[{x, index}, index[[1]] * ToExpression@ StringSplit[x][[2]] ] , listOfOrderedHands ] (* toy input result: 6440 user input result: 250957639 *)
algorithm explanation
Basically just use SortBy to sort the input. Bigger hand at the bottom. Then for each item, multiple the index of the line by its bid. Then total them.
The gist is to figure out what's the ordering function for the sort.
SortBy takes a list of functions {f1,f2, etc}. when f1 is a tie, it uses f2.
In our case, f1 sort by the type of hand. The f1 return a list like this e.g. {3, 2, 0, 0, 0} 3 means there's 3 chars are the same, then 2 means there's a pair. this is done by, e.g.
Function[{y}, PadRight[y, 5, 0]]@ Values@ ReverseSort@ CharacterCounts@ "QQQJA"
our f2 is this
Function@ Lookup[ sortTable, (Characters@ "QQQJA")]
which return the string into a list of chars, then turn each char into a ordering number by sortTable.