Created
December 2, 2022 06:50
-
-
Save MatthiasPortzel/165398b77128c8ea7611535bbd25e7bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Prolog doesn't have functions, per se. It has statements that are true. | |
% For example, addition(2, 2, 4) can be read as "two plus two is 4". | |
% And it doesn't return anything. | |
% It can sometimes be helpful to think of the third value as a return value, | |
% however, the power of Prolog is that the statements can be read both "forward" and "backward" | |
% Prolog is like a deduction machine. | |
% Given a list of facts, it will deduce the values of any variables (things that start with capital letters) | |
% For example, rps ("rock paper sissors") is defined below. | |
% In this program it is used like `rps("A", "X", Outcome)`. | |
% (That is, the plays are determined first, then the outcome is determined.) | |
% But in part 2, you could use the same `rps` function and pass in an outcome and a play, | |
% and it would tell you what the other player must have played, by filling in the blanks. | |
% (In practice, you would have to tweak it a bit, since it treats "outcomes" as strings right now, | |
% and part 2 treats outcomes as X/Y/Z.) | |
% Thier play, my play, outcome (for me) | |
rps("A", "X", "draw"). | |
rps("B", "Y", "draw"). | |
rps("C", "Z", "draw"). | |
% Rock | |
rps("A", "Y", "win"). | |
rps("A", "Z", "lose"). | |
% Paper | |
rps("B", "Z", "win"). | |
rps("B", "X", "lose"). | |
% Sissors | |
rps("C", "X", "win"). | |
rps("C", "Y", "lose"). | |
% My play, and points | |
pointsFromPlay("X", 1). | |
pointsFromPlay("Y", 2). | |
pointsFromPlay("Z", 3). | |
% Outcome, and points | |
pointsFromOutcome("win", 6). | |
pointsFromOutcome("draw", 3). | |
pointsFromOutcome("lose", 0). | |
% Thier play, my play, outcome | |
% The `:-` construction can be read as "where" | |
% That is, the expression before `:-` is only true when all the expressions after it are true | |
% You can use this to create statements that are condintially true in Prolog, | |
% but this statement should always be able to find a true value, for a value input | |
% I just `:-` to tell Prolog it needs to find values for these variables before evaluating the main expression | |
scoreGame(ThierPlay, MyPlay, Score) :- | |
pointsFromPlay(MyPlay, PlayPoints), | |
rps(ThierPlay, MyPlay, Outcome), | |
pointsFromOutcome(Outcome, OutcomePoints), | |
Score is PlayPoints + OutcomePoints. | |
%?- scoreGame("rock", "sissors", X). | |
% list of games, total score | |
scoreGames([], 0). | |
scoreGames([[ThierPlay,MyPlay]|Rest], TotalScore) :- | |
scoreGame(ThierPlay, MyPlay, HeadScore), | |
scoreGames(Rest, RestScore), | |
TotalScore is HeadScore + RestScore. | |
% You can run this program with `brew install gnu-prolog` | |
% Then `gprolog --consult-file aoc_day2_part1.pl` | |
% Then paste the following expression at the prompt. | |
% scoreGames([["A", "Y"], ["B", "X"], ["C", "Z"]], X). | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment