Skip to content

Instantly share code, notes, and snippets.

@MatthiasPortzel
Created December 2, 2022 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MatthiasPortzel/165398b77128c8ea7611535bbd25e7bf to your computer and use it in GitHub Desktop.
Save MatthiasPortzel/165398b77128c8ea7611535bbd25e7bf to your computer and use it in GitHub Desktop.
% 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