diff --git a/day7.pl b/day7.pl index 4b595de..afd37c9 100644 --- a/day7.pl +++ b/day7.pl @@ -1,55 +1,51 @@ -:- use_module(library(dcg/basics)). -:- use_module(library(pio)). - -sorted_hand([X,X,X,X,X], five) :- !. -sorted_hand([X,X,X,X|_], four) :- !. +% 0 for the joker. the other clauses are just the hand shapes +% sorry about all the cuts +sorted_hand([0|Rest], H) :- sorted_hand(Rest, H0), promote(H0, H), !. +sorted_hand([X,X,X,X,X], five) :- !. +sorted_hand([X,X,X,X|_], four) :- !. sorted_hand([X,X,X,Y,Y], full_house) :- !. sorted_hand([X,X,Y,Y,Y], full_house) :- !. -sorted_hand([X,X,X|_], three) :- !. -sorted_hand([X,X|Rest], two_pairs) :- sorted_hand(Rest, pair), !. -sorted_hand([X,X|_], pair) :- !. -sorted_hand([_|Rest], H) :- sorted_hand(Rest, H), !. -sorted_hand(_, junk). +sorted_hand([X,X,X|_], three) :- !. +sorted_hand([X,X|Rest], two_pairs) :- sorted_hand(Rest, pair), !. +sorted_hand([X,X|_], pair) :- !. +sorted_hand([_|Rest], H) :- sorted_hand(Rest, H), !. +sorted_hand([], junk). -hand(Cards, H) :- - msort(Cards, S), - sorted_hand(S, H). +promote(junk, pair). +promote(pair, three). +promote(two_pairs, full_house). +promote(three, four). +promote(four, five). -rank(junk, 0). -rank(pair, 1). -rank(two_pairs, 2). -rank(three, 3). +hand(Cards, H) :- msort(Cards, S), sorted_hand(S, H). + +rank(junk, 0). +rank(pair, 1). +rank(two_pairs, 2). +rank(three, 3). rank(full_house, 4). -rank(four, 5). % lol -rank(five, 6). +rank(four, 5). % lol +rank(five, 6). hand_rank(C, R) :- hand(C, H), rank(H, R). compare_rank(X, C1, C2) :- hand_rank(C1, R1), hand_rank(C2, R2), compare(X, R1, R2). -compare_hand(X, C1-_, C2-_) :- compare_rank(X, C1, C2), X \= (=). -compare_hand(X, C1-_, C2-_) :- compare_rank(=, C1, C2), compare(X, C1, C2). +compare_hand(X, C1-_, C2-_) :- + compare_rank(X0, C1, C2), + (X0 = (=) -> compare(X, C1, C2) ; X = X0). +total(Xs, R) :- total(1, Xs, R). + total(_, [], 0). total(I, [_-X|Xs], R) :- I1 is I + 1, total(I1, Xs, R0), R is R0 + (I * X). -total(Xs, R) :- total(1, Xs, R). - -value(C, N) :- - char_code(C, N0), - char_code('0', Z), - N is N0 - Z, - N >= 0, N =< 9. -value('T', 10). -value('J', 11). -value('Q', 12). -value('K', 13). -value('A', 14). +:- use_module(library(dcg/basics)). card(V) --> [X], {char_code(C, X), value(C, V)}. cards(Cs) --> card(A), card(B), card(C), card(D), card(E), {Cs = [A,B,C,D,E]}. @@ -59,13 +55,33 @@ line(Cs-B) --> cards(Cs), spaces, bid(B). lines([]) --> "\n" ; []. lines([L|Ls]) --> line(L), "\n", lines(Ls). +value('T', 10). +value('J', 11). +value('Q', 12). +value('K', 13). +value('A', 14). +value(C, N) :- char_code(C, N0), N is N0 - 0x30, N >= 0, N =< 9. + part1(File) :- phrase_from_file(lines(Ls), File), - % length(Ls, N), writeln(N), predsort(compare_hand, Ls, Sorted), total(Sorted, R), writeln(R), !. +joker(11, 0). +joker(X, X) :- X \= 11. +part1_to_part2(Xs-B, Ys-B) :- maplist(joker, Xs, Ys). + +with_hand(Xs-B, H-Xs-B) :- hand(Xs, H). + +part2(File) :- + phrase_from_file(lines(Ls0), File), + maplist(part1_to_part2, Ls0, Ls), + predsort(compare_hand, Ls, Sorted), + total(Sorted, R), + writeln(R), !. + % vim: set ft=prolog : +% vim what the fuck is "gringo"