Intro
Imagine a list of elements and their outcomes when some non-commutative function is applied to them. For example, we will use the elements Rock
, Paper
, and Scissors
, the outcomes Win
, Lose
, and Tie
, and an operator *
such that X*Y
= what would happen if you played X
against Y
As a list, you might write it this way:
[Rock*Rock=Tie, Rock*Paper=Loss, Rock*Scissors=Win,
Paper*Rock=Win, Paper*Paper=Tie, Paper*Scissors=Loss,
Scissors*Rock=Loss, Scissors*Paper=Win, Scissors*Scissors=Tie]
In table form, it might look like this:
top*left | Rock | Paper | Scissors |
---|---|---|---|
Rock | Tie | Win | Loss |
Paper | Loss | Tie | Win |
Scissors | Win | Loss | Tie |
One might observe that for any pair of elements, there is a pair of outcomes. For the unordered pair (Rock,Paper)
, Rock*Paper
gives Loss
and Paper*Rock
gives Win
.
You might think of a function which takes a pair of elements and outputs a pair of outcomes given by the table. In our initial example, that'd be (Rock,Paper) => (Loss,Win)
A few more examples:
(Rock,Rock) => (Tie,Tie)
(Paper,Scissors) => (Win,Loss)
(Paper,Paper) => (Tie,Tie)
Note that order of input and output doesn't really matter here, since we're just asking which outcomes exist at all between the two elements.
Finally, consider the inverse to this function, which takes a pair of outcomes as input and outputs tall pairs of elements which can have both outcomes.
Here are all possible distinct inputs and their outputs for the example case:
(Win, Win) =>
(Win, Loss) => (Rock,Paper), (Paper,Scissors), (Scissors,Rock)
(Win, Tie) =>
(Loss, Loss) =>
(Loss, Tie) =>
(Tie, Tie) => (Rock,Rock), (Paper,Paper), (Scissors,Scissors)
Note again that order doesn't matter here, so
(Win,Loss) => (Rock,Paper), (Paper,Scissors), (Scissors,Rock)
(Loss,Win) => (Rock,Paper), (Paper,Scissors), (Scissors,Rock)
(Win,Loss) => (Paper,Rock), (Scissors,Paper), (Scissors,Rock)
(Win,Loss) => (Scissors,Rock), (Rock,Paper), (Paper,Scissors)
are all valid.
Implementing this inverse is your challenge.
Challenge
Write a program or function which does the following:
- Takes a list of ordered element pairs and their outcomes when some non-commutative function is applied, referred to as the "Interaction Table" from here onward. This can be done in any consistent reasonable format, specified by the solver.
- Takes a single unordered pair of outcomes
x,y
as a second input, referred to as the "Given Pair" from here onward. This can be done in any consistent reasonable format, specified by the solver. - Outputs a list of all unique unordered pairs of elements
a,b
such that, according to the Interaction Table,a*b
is one ofx,y
andb*a
is the other. This can be done in any consistent reasonable format, specified by the solver.
This is code-golf, So shortest code in bytes wins.
More specification
- The Interaction Table does not actually have to be a literal table. It can be taken in any reasonable format, standard I/O etc. Just remember to specify exactly how you take input, especially if it's somewhat unusual.
- Instead of taking the Given Pair as a second input, your program/function may take only the Interaction Table as input and output a program/function which takes the Given Pair as its only input and provides the expected output for the challenge.
- You may restrict elements and outcomes to a reasonable degree, e.g. "only integers" / "only alphabetical strings" is fine, but "only digits 0-9" is not.
- Since outputs will always be pairs of elements, you don't need to use a second delimiter to separate pairs, only individual elements. e.g. both
(A B) => (1 2) (3 4)
andA B => 1 2 3 4
are both valid formats. - You may assume that there are no missing interactions, i.e. every element within the Interaction Table will be paired with every other element and itself in each possible permutation.
- You may assume that the Interaction Table is given in some standard order, if that helps you in some way.
- You may not assume that every Given Pair will have an output. In these cases, any falsy output or no output is fine, so long as you don't output an element pair.
- You may not output duplicate pairs.
(A,B) => (1,2),(1,2)
is not valid, and since pairs are unordered,(A,B) => (1,2),(2,1)
is also not valid.
More examples
Here is another example of a possible Interaction Table input
(("AxA=1","AxB=1","AxC=2"),("BxA=2","BxB=3","BxC=2"),("CxA=1","CxB=2","CxC=1"))
Which can correspond to this literal table
x | A | B | C |
---|---|---|---|
A | 1 | 2 | 1 |
B | 1 | 3 | 2 |
C | 2 | 2 | 1 |
Some example Given Pairs and their outputs
(1,1) => (A,A),(C,C)
(2,2) => (B,C)
(2,3) =>
(1,2) => (A,B),(A,C)
Another possible Interaction Table input
["What","What","Yeah"],["What","Who","Yeah"],["Who","What","Nah"],["Who","Who","Yeah"]
Which can correspond to this literal table
x | What | Who |
---|---|---|
What | Yeah | Nah |
Who | Yeah | Yeah |
Some example Given Pairs and their outputs
"Nah" "Yeah" => "Who" "What"
"Yeah" "Nah" => "Who" "What"
"Nah" "Nah" =>
"Yeah" "Yeah" => "What" "What" "Who" "Who"
One more possible Interaction Table input
"0 0 a 0 1 b 1 0 c 1 1 d"
Which can correspond to this literal table
x | 0 | 1 |
---|---|---|
0 | a | c |
1 | b | d |
uninvert(invert(f()))
is not necessarily the same asf()
. Not that this is essential for this challenge, of course... \$\endgroup\$