answer(Answer) :- input(Input), convert_input(Input, Hands, Bets), convlist(score, Hands, Scores), zip(Scores, Bets, ScoresBets), sort(ScoresBets, SortedScoreBets), length(Input, NHands), length(VarList, NHands), scanl([_, Prev, Curr]>>(Curr is Prev + 1), VarList, 0, [_ | Ranks]), zip(Ranks, SortedScoreBets, RankScoreBets), foldl([Rank-(_-Bet), Prev, Sum]>>(Sum is Prev + Rank*Bet), RankScoreBets, 0, Answer). % score(Hand, Score) gets the score for one hand, that can be directly compared. score([A, B, C, D, E], Score) :- type([A, B, C, D, E], Type), Score is E + 100*D + (100**2)*C + (100**3)*B + (100**4)*A + (100**5)*Type. type([1, 1, 1, 1, 1], 7). type(Hand, 7) :- count_hand(Hand, 5, _). type(Hand, 6) :- count_hand(Hand, 4, _). type(Hand, 5) :- count_hand(Hand, 3, 2). type(Hand, 4) :- count_hand(Hand, 3, 3). type(Hand, 3) :- count_hand(Hand, 2, 3). type(Hand, 2) :- count_hand(Hand, 2, 4). type(Hand, 1) :- count_hand(Hand, 1, _). count_hand(Hand, NMaxCard, NUniqueCards) :- exclude(=:=(1), Hand, NoJokerHand), maplist(count(NoJokerHand), NoJokerHand, Counts), max_member(MaxCountNoJoker, Counts), count(Hand, 1, NJokers), NMaxCard is MaxCountNoJoker + NJokers, sort(NoJokerHand, Uniques), length(Uniques, NUniqueCards). % count(List, Elem, Count), Count = number of occurences of Elem in List. count([], _, 0). count([X | Cdr], X, N) :- count(Cdr, X, NRest), N is NRest + 1. count([Y | Rest], X, N) :- Y =\= X, count(Rest, X, N). % card(Ascii, Value) converts between card ascii value and internal values card(74, 1). % J card(84, 10). card(81, 12). card(75, 13). card(65, 14). % TQKA card(Char, Card) :- Char >= 48, Char =< 57, Card is Char - 48. % zip 2 lists into a map zip(List1, List2, Map) :- maplist([A, B, A-B]>>(true), List1, List2, Map). % convert_input(InputList, Cards, Bets) convert_input([], [], []). convert_input([[Cards, Bet] | Cdr], [[C1, C2, C3, C4, C5] | HandCdr], [Bet | BetCdr]) :- string_to_list(Cards, [A1, A2, A3, A4, A5]), card(A1, C1), card(A2, C2), card(A3, C3), card(A4, C4), card(A5, C5), convert_input(Cdr, HandCdr, BetCdr).