aoc23/07/part2.pl

55 lines
2.1 KiB
Perl
Raw Normal View History

2023-12-07 03:50:17 -06:00
answer(Answer) :-
2023-12-07 17:04:57 -06:00
input(Input), convert_input(Input, Hands, Bets),
2023-12-07 03:50:17 -06:00
convlist(score, Hands, Scores),
zip(Scores, Bets, ScoresBets),
2023-12-07 17:04:57 -06:00
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).
2023-12-07 03:50:17 -06:00
% score(Hand, Score) gets the score for one hand, that can be directly compared.
score([A, B, C, D, E], Score) :-
2023-12-07 15:30:49 -06:00
type([A, B, C, D, E], Type),
2023-12-07 13:00:26 -06:00
Score is E + 100*D + (100**2)*C + (100**3)*B + (100**4)*A + (100**5)*Type.
2023-12-07 03:50:17 -06:00
2023-12-07 15:30:49 -06:00
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, _).
2023-12-07 03:50:17 -06:00
2023-12-07 15:30:49 -06:00
count_hand(Hand, NMaxCard, NUniqueCards) :-
2023-12-07 15:43:09 -06:00
exclude(=:=(1), Hand, NoJokerHand),
2023-12-07 15:30:49 -06:00
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).
2023-12-07 03:50:17 -06:00
% card(Ascii, Value) converts between card ascii value and internal values
card(74, 1). % J
2023-12-07 15:30:49 -06:00
card(84, 10). card(81, 12). card(75, 13). card(65, 14). % TQKA
2023-12-07 03:50:17 -06:00
card(Char, Card) :- Char >= 48, Char =< 57, Card is Char - 48.
% zip 2 lists into a map
2023-12-07 17:04:57 -06:00
zip(List1, List2, Map) :- maplist([A, B, A-B]>>(true), List1, List2, Map).
2023-12-07 13:00:26 -06:00
% 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).