72
\$\begingroup\$

In the card game Magic: the Gathering there are five different colours, which represent loose affiliations of cards, White (W), Blue (U), Black (B), Red (R) and Green (G). These are often arranged in a pentagon as follows:

  W
G   U
 R B

Both in the lore of MtG as well as in many card mechanics, adjacent colours in this pentagon are usually considered allies, and non-adjacent (sort of opposite) colours are considered enemies.

In this challenge, you'll be given two colours and should determine their relationship.

The Challenge

You're given any two distinct characters from the set BGRUW. You may take these as a two-character string, a string with a delimiter between the characters, two separate character values, two singleton strings, two integers representing their code points, or a list or set type containing two characters/strings/integers.

Your output should be one of two distinct and consistent values of your choice, one which indicates that the two colours are allies and one which indicates that they are enemies. One of those two values may be no output at all.

You may write a program or a function and use any of the our standard methods of receiving input and providing output.

You may use any programming language, but note that these loopholes are forbidden by default.

This is , so the shortest valid answer – measured in bytes – wins.

Test Cases

There are only 20 possible inputs, so I'll list them all.

Friends:

WU   UB   BR   RG   GW   UW   BU   RB   GR   WG

Foes:

WB   UR   BG   RW   GU   BW   RU   GB   WR   UG
\$\endgroup\$
6
  • 35
    \$\begingroup\$ Up next: implement the core rules :P \$\endgroup\$ Mar 14, 2017 at 14:56
  • 12
    \$\begingroup\$ @CaptainMan i will upvote you if you can make it fit in a 30k character post :) \$\endgroup\$
    – Walfrat
    Mar 14, 2017 at 15:58
  • \$\begingroup\$ @Walfrat 30k? Should be possible \$\endgroup\$ Mar 15, 2017 at 21:03
  • 2
    \$\begingroup\$ @IvanKolmychek from the most unexpected alliances comes the most unexpected outcomes. \$\endgroup\$
    – aluriak
    Mar 19, 2017 at 1:59
  • 1
    \$\begingroup\$ Fun fact: Magic: The gathering is turing complete :) \$\endgroup\$ Mar 20, 2017 at 8:04

48 Answers 48

1
2
2
\$\begingroup\$

///, 40 bytes

//i//R///G///W///U///B///i/1/WUBRGWGRBUW

Try it online!

Since /// has no other way of taking input, you need to put your input after the first /. An example of checking WG:

/WG/i//R///G///W///U///B///i/1/WUBRGWGRBUW

Itflabtijtslwi, 52 bytes

GGjGGGGkGG/jk/i//R///G///W///U///B///i/1/WUBRGWGRBUW

Try it online!

Outputs a 1 if they are allies, otherwise outputs nothing.

The funny part is that it is actually a shorter answer than some "real" languages have.

You may be thinking, "You're not allowed to code the input in the program!" But you are allowed to do so if the language has no other way of getting input, as said here: meta.codegolf.stackexchange.com/a/10553/64159.

Thanks to Ørjan Johansen for the help with the Itflabtijtslwi port and making the interpreter. Very much.

\$\endgroup\$
6
  • \$\begingroup\$ Ah, okay. Didn't know about that. \$\endgroup\$
    – Riker
    Mar 14, 2017 at 15:29
  • \$\begingroup\$ The itflabtijtslwi won't work, first a GG...GG command only reads a single character, secondly it substitutes the other way around. Try something like GGjGGGGkGG/jk/i/. \$\endgroup\$ Mar 16, 2017 at 4:47
  • \$\begingroup\$ @ØrjanJohansen I made the edit, is that correct? Also, is there an online interpreter for itflabtijtslwi? I could not find one. \$\endgroup\$
    – sporkl
    Mar 16, 2017 at 13:48
  • \$\begingroup\$ Try it online! Stripped my Perl one into a TIO header/footer. Still large for comments. :( \$\endgroup\$ Mar 16, 2017 at 15:02
  • 1
    \$\begingroup\$ Sure. I just added the TIO hack to the Esolang wiki to make it official :) \$\endgroup\$ Mar 16, 2017 at 15:10
2
\$\begingroup\$

Python 2, 56 46 28 Bytes

print input()in"WUBRGWGRBUW"

Takes input as a string and returns True or False if it is in the string b. Try it here! Thanks to @Григорий Перельман for removing 10 bytes! Thanks @SparklePony for removing another 18 bytes!

\$\endgroup\$
0
2
\$\begingroup\$

Brain-Flak, 78 bytes

(([(({}[{}]))]<>)){({}())<>}([]()(([])[]([][][]({}{}({}))))){{}}{}({()<{{}}>})

Try it online!

This improves on DJMcMayhem's answer by streamlining the comparisons. It also uses the negative absolute value directly instead of using extra instructions to reach the positive absolute value.

\$\endgroup\$
1
\$\begingroup\$

Batch, 62 bytes

@set s=WUBRGWGRBUW
@call set t=%%s:%1=%%
@if %s%==%t% echo 1

Outputs 1 for foes, nothing for friends.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 42 34 32 bytes

'WUBRGWGRBUW'.indexof($args)-ge0

Try it online!

Input is as a single string (e.g., RG), that is stringified $args and used as the .indexof() parameter for the color string. If the substring is not found, -1 is returned, so testing whether the result is -greater-than-or-equal to 0 suffices for a truthy/falsey output.

Saved two more bytes thanks to Philipp Leiß.

\$\endgroup\$
1
\$\begingroup\$

S.I.L.O.S, 53 bytes

loadLine
a=get 256
b=get 257
a*b
a%103
a%2
printInt a

Try it online!

Input as a commmand line argument Please do note that this uses the method from the most upvoted answer

\$\endgroup\$
1
1
\$\begingroup\$

PHP, 45 Bytes

I know if I use a mod solution from someone else, that I can do it much shorter.

the absolute difference mod 17 mod 5 is 1 or 2

<?=abs(ord($t=$argv[1])-ord($t[1]))%17%5+1&2;

golfed down by @Titus from 64 Bytes

<?=in_array((abs(ord(($t=$argv[1])[0])-ord($t[1]))%17)%5,[1,2]);

PHP, 72 Bytes

the absolute difference mod 17 foes contains a digit between 3 and 5

<?=preg_match("#^[^3-5]+$#",(abs(ord(($t=$argv[1])[0])-ord($t[1]))%17));

PHP, 88 Bytes

the absolute difference mod 17 friends have a digit sum of 2 or 7

<?=in_array(array_sum(str_split((abs(ord(($t=$argv[1])[0])-ord($t[1]))%17))),[2,7])?1:0;

PHP >= 7.1, 81 Bytes

$p=strpos($s=WUBRG,($i=$argv[1])[0]);echo$i[1]==$s[$p!=4?$p+1:0]|$i[1]==$s[$p-1];

http://sandbox.onlinephpfunctions.com/code/9136a36084ecb5b397466e839210b50a88d8fe98

\$\endgroup\$
1
  • \$\begingroup\$ Oh well ... stolen arithmetics: echo ord($argn)*ord($argn[1])%51<9; is another 9 bytes shorter (35 bytes). \$\endgroup\$
    – Titus
    Mar 15, 2017 at 4:27
1
\$\begingroup\$

Java 8, 17 16 14 bytes

This is simply a Java lambda version of the same arithmetic solution everyone else is using. Takes two integral/character arguments containing the color codes as ASCII. Returns true if they are friends, false if foes.

Golfed:

a->b->a*b%51<9

Ungolfed:

import java.util.function.*;

public class MagicTheGatheringFriendsOrFoes {

  private static final char[][] FRIENDS = new char[][] { { 'W', 'U' }, { 'U', 'B' }, { 'B', 'R' }, { 'R', 'G' },
      { 'G', 'W' }, { 'U', 'W' }, { 'B', 'U' }, { 'R', 'B' }, { 'G', 'R' }, { 'W', 'G' } };

  private static final char[][] FOES = new char[][] { { 'W', 'B' }, { 'U', 'R' }, { 'B', 'G' }, { 'R', 'W' },
      { 'G', 'U' }, { 'B', 'W' }, { 'R', 'U' }, { 'G', 'B' }, { 'W', 'R' }, { 'U', 'G' } };

  public static void main(String[] args) {
    System.out.println("Friends: expect true");
    for (char[] friends : FRIENDS) {
      boolean result = f().apply(Integer.valueOf(friends[0])).apply(Integer.valueOf(friends[1]));
      System.out.println("(" + friends[0] + "," + friends[1] + ") = " + result);
    }

    System.out.println();
    System.out.println("Foes: expect false");
    for (char[] foes : FOES) {
      boolean result = f().apply(Integer.valueOf(foes[0])).apply(Integer.valueOf(foes[1]));
      System.out.println("(" + foes[0] + "," + foes[1] + ") = " + result);
    }
  }

  private static Function<Integer, IntFunction<Boolean>> f() {
    return a -> b -> a * b % 51 < 9;
  }
}
\$\endgroup\$
6
  • \$\begingroup\$ "This is simply a Java lambda version of the same arithmetic solution everyone else is using." I believe you're only the third person using it. ;) \$\endgroup\$ Mar 14, 2017 at 8:08
  • \$\begingroup\$ You can remove the final ; as it's not part of the function itself. Also, you can curry it: a->b->a*b%51<9 for 14 bytes total. \$\endgroup\$ Mar 16, 2017 at 9:59
  • \$\begingroup\$ Finally, you counted 1 byte too much: your answer is 16 bytes, but you say it's 17. \$\endgroup\$ Mar 16, 2017 at 10:06
  • \$\begingroup\$ @OlivierGrégoire you are correct, the trailing ; should not be counted. As far as currying, I can't quite get that to compile no matter how I set up the second function. What approach should I take here? \$\endgroup\$
    – user18932
    Mar 16, 2017 at 13:28
  • \$\begingroup\$ interface FunctionA { FunctionB apply(int a); } interface FunctionB { boolean apply(int b); } then you use it like this: FunctionA f = a->b->a*b%51<9;. \$\endgroup\$ Mar 16, 2017 at 13:45
1
\$\begingroup\$

bash, 23 bytes

[[ WUBRGWGRBUW =~ $1 ]]

Exits/returns 0 (success/true) if friends, 1 (failure/false) if enemies.

This works by using the input string (for example, WU) as a regular expression using bash's builtin [[, which tests various things, in this case, the =~ operator of [[ is used to see if the first string WUBRGWGRBUW matches the regex (input string). Since the regex is not anchored by default, so long as the input string occurs anywhere in the "checked" string, [[ returns the status code 0, meaning the test result was true. If the input character pair did not occur anywhere in the string, it returns status code 1, meaning the test result was false. The tested string is a concatenation of all possible adjacent friend characters, so it's matched only by the friend-pair inputs.

Test:

for pair in WU UB BR RG GW UW BU RB GR WG WB UR BG RW GU BW RU GB WR UG
do
  bash -c '[[ WUBRGWGRBUW =~ $1 ]]' - $pair
  echo $pair $?
done
\$\endgroup\$
1
\$\begingroup\$

OIL, 77 bytes

Third-worst answer, but hey, it's OIL. Commented for clarity (remove spaces and C++-style comments for execution)

WU //storage, this just nops
UB
BR
RG
GW
UW
BU
RB
GR
WG
5  // read user input into line 10 (overwriting this line)
10
10 // test if what's in line 10 (the user input) &
10
0  // is identical to what's in line 0 (the first string) *
26 // if so, jump to line 26 (marked with %)
17 // else, jump to the next line
8  // increment line 14 (marked with *)
14
10 // test if line 14 is identical to
14
11 // what's in line 11 (a "10")
27 // if so, we checked all strings; so jump to line 27 (marked with $)
24 // else jump to the next line
6  // jump to line 12 (marked with &)
12
4  // print what's in line 4 ("GW" ≙ friend) %
4  // print what's in line 0 ("WU" ≙ foe) $

Prints GW if the colours are allies, WU otherwise (and if any unexpected input occurs).

\$\endgroup\$
1
\$\begingroup\$

Brain-Flak, 90 bytes

(<({}[{}])>)([[]()]((([])[][][])[][])){([({}<>)])<>}{}<>({<({}<>({}))>(){[()](<{}>)}{}<>})

Try it online!

This beats the previous Brain-Flak answer by swapping getting the absolute value of the difference with creating negative copies of the differences to check. It also has slightly better number generation and difference checking

\$\endgroup\$
1
\$\begingroup\$

Whitespace, 60 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   S _Read_input_as_character][T   T   T   _Retrieve_first_input][S N
S _Duplicate_first_input][S N
S _Duplicate_first_input][T N
T   S _Read_input_as_character][T   T   T   _Retrieve_second_input][T   S S N
_Multiply][S S S T  T   S S T   T   T   N
_Push_103][T    S T T   _Modulo][S S S T    S N
_Push_2][T  S T T   _Modulo][T  N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Port of @Arnauld's 15-bytes JavaScript answer, so also outputs 0 for friends and 1 for foes.

Try it online (with raw spaces, tabs, and new-lines only).

Explanation in pseudo-code:

Integer a = read STDIN as character
Integer b = read STDIN as character
Integer t = a * b
t = t % 103
t = t % 2
Print t as integer to STDOUT
\$\endgroup\$
0
\$\begingroup\$

Pyth, 16 bytes

gx+J"WUBRGW"_JzZ

Test suite available online.

Explanation

gx+J"WUBRGW"_JzZ
   J"WUBRGW"      store string in variable J
  +         _J    concat J and reversed J
 x            z   get index of input in this string
g              Z  return if index >= 0 (will be -1 if not found)
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 20 bytes

a=>b=>(a-b)%9%5%3!=0

let F = a=>b=>(a-b)%9%5%3!=0
let ch = [87, 85, 66, 82, 71];

console.log('Friends:');
console.log('WU/UW', F(ch[0])(ch[1]), F(ch[1])(ch[0]));
console.log('UB/BU', F(ch[1])(ch[2]), F(ch[2])(ch[1]));
console.log('BR/RB', F(ch[2])(ch[3]), F(ch[3])(ch[2]));
console.log('RG/GR', F(ch[3])(ch[4]), F(ch[4])(ch[3]));
console.log('GW/WG', F(ch[4])(ch[0]), F(ch[0])(ch[4]));

console.log('Foes:');
console.log('WB/BW', F(ch[0])(ch[2]), F(ch[2])(ch[0]));
console.log('UR/RU', F(ch[1])(ch[3]), F(ch[3])(ch[1]));
console.log('BG/GB', F(ch[2])(ch[4]), F(ch[4])(ch[2]));
console.log('RW/WR', F(ch[3])(ch[0]), F(ch[0])(ch[3]));
console.log('GU/UG', F(ch[4])(ch[1]), F(ch[1])(ch[4]));

Takes input as ascii character codes, passed in as F(a)(b) (one character each). Returns true for friends, false for foes.

Thanks to Mistah Figgins for the modulo idea.

\$\endgroup\$
0
\$\begingroup\$

QBIC, 29 bytes

;?instr(@WUBRG`+@W`+_fB|,A)>0

Explanation:

;       Gets the color combination as one strintg, "UG"
?       Print --> will eventually yield -1 for allies and 0 otherwise
instr(  Get the index of one string in antother. 
@WUBRG` The string to be searced is all allies, (@...` creates a string called B$)
+@W`      and an extra 'W' that we don't want to flip (prevents 'WW')
+_fB|    and all allies flipped --> WUBRGWGRBUW
,A)    The string to look for: "UG"
>0     If A is found in B+G+fB, this is >0, and PRINT will show -1 (QBasic's TRUE value)
       It prints 0 in all other cases.

This would be two bytes shorter if we could say that any positive value is true, and 0 is false...

\$\endgroup\$
0
\$\begingroup\$

C#, 37 Bytes

(string s)=>"GWUBRGRBUWG".Contains(s)
\$\endgroup\$
0
\$\begingroup\$

Perl 5, 18 bytes

$_=WUBRGWGRBUW=~$_

Try it online!

Takes input as a two letter string, upper case. Outputs 1 (true) for allies, nothing (false) for enemies.

\$\endgroup\$
0
\$\begingroup\$

Thunno 2, 7 bytes

×.6/4Æ&

Try it online!

Link is to verify all test cases. Port of Arnauld's JS answer.

Explanation

×.6/4Æ&  # Implicit input as charcodes
×        # Multiply the two charcodes together
 .6/     # Divide this result by 0.6
    4Æ&  # Bitwise AND with 4
         # Implicit output
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.