Xah Talk Show 2024-01-26 Ep534 Advent of Code, Day 7, Live Coding in WolframLang

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

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.

WolframLang advent 2023 day 7 2024-01-26
WolframLang advent 2023 day 7 2024-01-26
(* 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.