Magic the Gathering: Friends or Foes?

68

6

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

Martin Ender

Posted 2017-03-13T16:54:31.207

Reputation: 184 808

33Up next: implement the core rules :P – Captain Man – 2017-03-14T14:56:09.900

12@CaptainMan i will upvote you if you can make it fit in a 30k character post :) – Walfrat – 2017-03-14T15:58:30.747

@Walfrat 30k? Should be possible – Not that Charles – 2017-03-15T21:03:56.287

(offtopic) This separation seems strange to me, kind of an artificial limit on amount of combinations for decks. For instance, Blue-Green Simics and Black-White Orzhov both feel organic and kick ass. :) – Ivan Kolmychek – 2017-03-16T15:10:23.597

2@IvanKolmychek from the most unexpected alliances comes the most unexpected outcomes. – aluriak – 2017-03-19T01:59:47.433

1Fun fact: Magic: The gathering is turing complete :) – Matthew Roh – 2017-03-20T08:04:30.167

Answers

81

JavaScript (ES6),  26 23 17 15  14 bytes

Takes input as two ASCII codes in currying syntax (a)(b). Returns 4 for friends or 0 for foes.

a=>b=>a*b/.6&4

Try it online!

How?

NB: only the integer quotient of the division by 0.6 is shown below.

Combo | a  | b  | a*b  | / 0.6 | AND 4
------+----+----+------+-------+------
  WU  | 87 | 85 | 7395 | 12325 |   4
  UB  | 85 | 66 | 5610 |  9350 |   4
  BR  | 66 | 82 | 5412 |  9020 |   4
  RG  | 82 | 71 | 5822 |  9703 |   4
  GW  | 71 | 87 | 6177 | 10295 |   4
  UW  | 85 | 87 | 7395 | 12325 |   4
  BU  | 66 | 85 | 5610 |  9350 |   4
  RB  | 82 | 66 | 5412 |  9020 |   4
  GR  | 71 | 82 | 5822 |  9703 |   4
  WG  | 87 | 71 | 6177 | 10295 |   4
------+----+----+------+-------+------
  WB  | 87 | 66 | 5742 |  9570 |   0
  UR  | 85 | 82 | 6970 | 11616 |   0
  BG  | 66 | 71 | 4686 |  7810 |   0
  RW  | 82 | 87 | 7134 | 11890 |   0
  GU  | 71 | 85 | 6035 | 10058 |   0
  BW  | 66 | 87 | 5742 |  9570 |   0
  RU  | 82 | 85 | 6970 | 11616 |   0
  GB  | 71 | 66 | 4686 |  7810 |   0
  WR  | 87 | 82 | 7134 | 11890 |   0
  UG  | 85 | 71 | 6035 | 10058 |   0

Previous approach, 15 bytes

Takes input as two ASCII codes in currying syntax (a)(b). Returns 0 for friends or 1 for foes.

a=>b=>a*b%103%2

Try it online!

How?

Combo | a  | b  | a*b  | MOD 103 | MOD 2
------+----+----+------+---------+------
  WU  | 87 | 85 | 7395 |    82   |   0
  UB  | 85 | 66 | 5610 |    48   |   0
  BR  | 66 | 82 | 5412 |    56   |   0
  RG  | 82 | 71 | 5822 |    54   |   0
  GW  | 71 | 87 | 6177 |   100   |   0
  UW  | 85 | 87 | 7395 |    82   |   0
  BU  | 66 | 85 | 5610 |    48   |   0
  RB  | 82 | 66 | 5412 |    56   |   0
  GR  | 71 | 82 | 5822 |    54   |   0
  WG  | 87 | 71 | 6177 |   100   |   0
------+----+----+------+---------+------
  WB  | 87 | 66 | 5742 |    77   |   1
  UR  | 85 | 82 | 6970 |    69   |   1
  BG  | 66 | 71 | 4686 |    51   |   1
  RW  | 82 | 87 | 7134 |    27   |   1
  GU  | 71 | 85 | 6035 |    61   |   1
  BW  | 66 | 87 | 5742 |    77   |   1
  RU  | 82 | 85 | 6970 |    69   |   1
  GB  | 71 | 66 | 4686 |    51   |   1
  WR  | 87 | 82 | 7134 |    27   |   1
  UG  | 85 | 71 | 6035 |    61   |   1

Initial approach, 23 bytes

Takes input as a 2-character string. Returns true for friends or false for foes.

s=>parseInt(s,35)%9%7<3

Try it online!

Arnauld

Posted 2017-03-13T16:54:31.207

Reputation: 111 334

10Ah, finally something fun. :) – Martin Ender – 2017-03-13T17:28:20.950

4Fantastic find! – Greg Martin – 2017-03-14T23:48:52.720

Is there some clever maths I'm not aware of here or did you just brute force different modulos until you got one that worked? – FourOhFour – 2017-03-19T18:44:24.570

@FourOhFour It was brute forced. I think this is the smallest double modulo solution. But a port of this answer (which is using a comparison) would actually be one byte shorter.

– Arnauld – 2017-03-19T19:24:25.107

So basically you brute-forced the 103 module to gather results which are either odd or even, right? – OddDev – 2017-03-20T10:10:35.810

1@OddDev I actually tested all bits, not just the least significant one. For instance, a*b%290&8 would work just as well (producing 0 for friends or 8 for foes). – Arnauld – 2017-03-20T10:49:55.307

@Arnauld Interesting... Thank you! Btw, would be nice to have a blog-post or something about it :) – OddDev – 2017-03-20T15:13:58.077

37

Jelly, 6 bytes

ạg105Ị

Takes two code points as argument. Yields 1 for friends, 0 for foes.

Try it online!

Background

Let n and m be the code points of two input characters. By taking |n - m|, we need to concern ourselves only with all 2-combinations of characters. The following table shows all 2-combinations of characters the the corresponding absolute differences.

WU  2
UB 19
BR 16
RG 11
GW 16

WB 21
UR  3
BG  5
RW  5
GU 14

All foe combinations are divisible by 3, 5, or 7, but none of the friend combinations this, so friends are exactly those that are co-prime with 3 × 5 × 7 = 105.

How it works

ạg105Ị  Main link. Left argument: n (code point). Right argument: m (code point)

ạ       Yield the absolute difference of n and m.
 g105   Compute the GCD of the result and 105.
     Ị  Insignificant; return 1 if the GCD is 1, 0 if not.

Dennis

Posted 2017-03-13T16:54:31.207

Reputation: 196 637

Nicely spotted! Why is the absolute value necessary? (I tried it online and it didn't give the right answer; but mathematically it shouldn't matter.) – Greg Martin – 2017-03-14T23:49:47.737

@GregMartin It isn't necessary; signed difference would work just as well. Subtraction is _ is Jelly. Did you use something else? – Dennis – 2017-03-15T00:26:59.460

Ah I see, I wrongly read as just absolute value, not absolute difference. – Greg Martin – 2017-03-15T04:15:01.247

35

Python 2, 19 bytes

"WUBRGWGRBUW".count

Try it online!

An anonymous function: returns 1 for friends and 0 for foes.

Lynn

Posted 2017-03-13T16:54:31.207

Reputation: 55 648

2How does this work? – stannius – 2017-03-15T23:27:01.783

1

@stannius https://www.tutorialspoint.com/python/string_count.htm

– Taemyr – 2017-03-16T11:55:23.960

21

Befunge-98, 13 12 bytes

~~-9%5%3%!.@

Try it online!

Prints 0 for friends and 1 for foes

This uses the difference between the ASCII values of the letters.

If we take the (((ASCII difference % 9) % 5) % 3), the values for the foes will be 0. Then, we not the value and print it.

Thanks to @Martin for the golf

MildlyMilquetoast

Posted 2017-03-13T16:54:31.207

Reputation: 2 907

Use Jelly for 9 bytes: IA%9%5%3¬ Edit Try It Online!

– Jonathan Allan – 2017-03-13T18:06:51.693

@JonathanAllan I see you already did! Nice. – MildlyMilquetoast – 2017-03-13T18:58:23.357

I actually morphed your method (using the actual, rather than absolute, difference) mod 9 mod 6, and used the fact that Jelly indexes into lists modularly to get it down to 7. I accredited you and linked here.

– Jonathan Allan – 2017-03-13T19:00:27.970

@JonathanAllan I came up with the mod 9 mod 6 method too, but Befunge doesn't have actual difference or an absolute value, so it wasn't as feasible – MildlyMilquetoast – 2017-03-13T19:02:06.223

18

Jelly, 8 7 bytes

Piggybacks off of Mistah Figgins's fabulous Befunge answer!

Iị390B¤

Try it online!

How?

As Mistah Figgins noted the decision may be made by taking the absolute difference between the ASCII values mod 9 mod 5 mod 3 - 0s are then friends and 1s and 2s are enemies.

If we instead take the (plain) difference mod 9 we find that friends are 1s, 2s, 7s, and 8s while enemies are 3s, 4s, 5s, and 6s.

The code takes the difference with I and then indexes into the length 9 list [1,1,0,0,0,0,1,1,0], which is 390 in binary, 390B. The indexing is both modular (so effectively the indexing performs the mod 9 for free) and 1-based (hence the 1 on the very left).

Jonathan Allan

Posted 2017-03-13T16:54:31.207

Reputation: 67 804

16

C++ template metaprogramming, 85 bytes

template<int A,int B,int=(A-B)%9%5%3>struct f;template<int A,int B>struct f<A,B,0>{};

less golfed:

template<int A, int B,int Unused=(((A-B)%9)%5)%3>
struct foe;
template<int A, int B>
struct foe<A,B,0>{};

As this is a metaprogramming language, a construct compiling or not is one possible output.

An instance of f<'W','B'> compiles if and only if 'W' and 'B' are foes.

Math based off Befunge answer.

Live example.

As C++ template metaprogramming is one of the worst golfing languages, anyone who is worse than this should feel shame. ;)

Yakk

Posted 2017-03-13T16:54:31.207

Reputation: 859

Seems like there are a total of two redundant whitespaces inside templates. – Yytsi – 2017-03-13T19:04:52.620

@TuukkaX fixed, d'oh – Yakk – 2017-03-13T19:24:19.527

14

Ruby, 22 19 bytes

->x,y{390[(x-y)%9]}

Input: ASCII code of the 2 characters. Output: 1 for allies, 0 for enemies.

How it works:

Get the difference between the 2 numbers modulo 9, use a bitmask (390 is binary 110000110) and get a single bit using the [] operator.

G B

Posted 2017-03-13T16:54:31.207

Reputation: 11 099

2Ah nice, I keep forgetting that integers can be indexed. +1 – Martin Ender – 2017-03-13T22:51:19.887

16 bytes : ->x,y{x*y%103%2} Note that 0 and 1 are reversed.

– Eric Duminil – 2017-03-15T14:04:32.347

1And 15 bytes with x*y%51>9 like everybody else. I think it would be unfair to the upvotes to change it so radically now. – G B – 2017-03-15T14:17:25.123

10

CJam, 8 bytes

{*51%9>}

An unnamed block that expects two character codes on top of the stack and replaces them with 0 (friends) or 1 (foes).

Try it online!

Explanation

Well, we've seen a lot of fun arithmetic solutions now, so I guess it's fine if I present my own one now. The closest to this I've seen so far is Steadybox's C solution. This one was found with the help of a GolfScript brute forcer I wrote some time ago for anarchy golf.

Here is what this one does to the various inputs (ignoring the order, because the initial multiplication is commutative):

xy   x    y    x*y   %51  >9

WU   87   85   7395    0   0
UB   85   66   5610    0   0
BR   66   82   5412    6   0
RG   82   71   5822    8   0
GW   71   87   6177    6   0
WB   87   66   5742   30   1
UR   85   82   6970   34   1
BG   66   71   4686   45   1
RW   82   87   7134   45   1
GU   71   85   6035   17   1

We can see how taking the product of the inputs modulo 51 nicely separates the inputs into large and small results, and we can use any of the values in between to distinguish between the two cases.

Martin Ender

Posted 2017-03-13T16:54:31.207

Reputation: 184 808

9

Röda, 30 22 21 bytes

Bytes saved thanks to @fergusq by using _ to take the values on the stream as input

{[_ in"WUBRGWGRBUW"]}

Try it online!

The function is run like push "WU" | f after assigning a name to the function

Explanation

{                      /* Declares an anonymous function */
 [                 ]   /* Push */
  _ in                 /* the boolean value of the value on the stream is in */
      "WUBRGWGRBUW"    /* this string */
}

user41805

Posted 2017-03-13T16:54:31.207

Reputation: 16 320

o_O lightning speed – Pavel – 2017-03-13T16:55:47.637

It's possible to save 5 bytes by reading the input values from the stream instead of taking parameters: {[(_.._)in"WUBRGWGRBUW"]}, but then the function must be called like [a, b] | f. – fergusq – 2017-03-13T17:01:57.210

9

05AB1E, 10 bytes

Returns 0 for friend and 1 for foe.

‘Û‹BWR‘ûIå

Try it online! or as a Test suite

Explanation

‘Û‹BWR‘     # push the string "RUGBWR"
       û    # palendromize (append the reverse minus the first char)
        Iå  # check if input is in this string

Emigna

Posted 2017-03-13T16:54:31.207

Reputation: 50 798

9

C, 33 32 29 24 22 bytes

#define f(k,l)k*l%51<9

Returns 1 if friends, 0 if foes.

Steadybox

Posted 2017-03-13T16:54:31.207

Reputation: 15 798

8

Vim, 22 21 bytes

CWUBRGWGRBUW<esc>:g/<c-r>"/d<cr>

Input: a single line containing the two characters.

Output: empty buffer if friends, buffer containing WUBRGWGRBUW if enemies.

Explanation

C                                 # [C]hange line (deletes line into " register and enters insert mode)
 WUBRGWGRBUW<esc>                 # insert this text and exit insert mode
                 :g/      /d<cr>  # delete all lines containing...
                    <c-r>"        # ... the previously deleted input

m-chrzan

Posted 2017-03-13T16:54:31.207

Reputation: 1 390

2You can do C instead of cw – user41805 – 2017-03-13T17:37:24.963

8

Japt, 6 bytes

Inspired by @Martin Ender's solution.

Takes an array of two char codes as input.

×%51<9

Try it online! | Test Suite

Returns true for friends, false for foes.

14-byte solution:

Takes two char codes as input

nV a /3%3 f ¦1

Try it online! | Test Suite

Explanation:

nV a /3%3 f ¦1
nV a             // Absolute value of: First input (implicit) - Second input
      /3%3 f     // Divide by 3, mod 3, then floor the result
             ¦1  // Return true if the result does not equals 1, otherwise return false

12-byte solution:

"WUBRGW"ê èU

Try it online! | Test Suite

Explanation:

"WUBRGW"ê èU
"WUBRGW"ê     // "WUBRGW" mirrored = "WUBRGWGRBUW"
          èU  // Returns the number of times U (input) is found

Returns 1 for friends and 0 for foes.

9-byte solution:

Inspired by @Arnauld's solution.

*V%24%B%2

Test Suite

Returns 1 for friends, 0 for foes.

11-byte solution:

inspired by @Mistah Figgins's solution.

nV %9%5%3¦0

Test Suite

Oliver

Posted 2017-03-13T16:54:31.207

Reputation: 7 160

8

Brain-Flak, 155, 147, 135 bytes

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

Try it online!

This is 134 bytes of code plus one byte penalty for the -a flag which enables ASCII input.

This works by finding the absolute difference between the inputs, and checking if they equal 2, 11, 16, or 19. If it does, the input is a friend, and it prints a 1. If it's not, it prints nothing. Since nothing in brain-flak corresponds to an empty stack, which is falsy, no output is a falsy value. (meta)

One thing I particularly like about this answer, is that the "absolute difference" snippet (that is, (([(({}[{}]))<>])){({}())<>}{}{}<>{}) is not stack clean, but it can still be used in this answer since we don't care which stack we end up on before encoding the possible differences.

On a later edit, I took advantage of this even more by abusing the leftovers on the stack that doesn't end up with the absolute difference on it. On the first revision, I popped both of them off to keep it slightly more sane. Not doing this gives two major golfs:

  1. Obviously, it removes the code to pop them: {}{}, but more importantly:

  2. It allows us to compress the 2, 11, 16, 19 sequence from

    (((((()()))[][][](){})[][]())[])
    

    to

    (((([])[][][])[]())()()())
    

    Fortunately, there is no extra code needed to handle these leftovers later, so they are just left on the alternate stack.

Since brain-flak is notoriously difficult to understand, here is a readable/commented version:

#Push the absolute difference of the two input characters. It is unknown which stack the result will end on
(([(({}[{}]))<>])){({}())<>}

#Push 2, 11, 16, 19, while abusing the values left on the stack from our "Absolute value" calculation
(((([])[][][])[]())()()())

#Pop a zero from the other stack and toggle back
<>{}<>

#While True
{

    #Move top over and duplicate the other top
    ({}<><(({}))>)

    #Equals?
    ({}[{}]<(())>){((<{}{}>))}{}

    #If so:
    {

        #Increment the number under the stack
        {}({}<({}())>)
        #Push a zero
        (<()>)

    }

    #Pop the zero
    {}

    #Go back to the other stack
    <>

#Endwhile
}

#Toggle back
<>

#Pop a zero
{}

James

Posted 2017-03-13T16:54:31.207

Reputation: 54 537

There's a push, pop you can remove, and you can push 0 in the if more efficiently to get down to 129: TIO

– Riley – 2017-03-13T19:02:00.687

@Riley Cool, thanks for the tip! I like having a commented version, so I'm going to wait until I can comprehend that version before updating. – James – 2017-03-13T21:52:27.097

It was only two minor changes. Here is the important part. My comments are in all caps, sorry if it looks like I'm yelling.

– Riley – 2017-03-13T21:56:02.817

7

Jelly, 14 bytes

“WUBRG”wЀIAÆP

Returns 1 for enemies and 0 for friends.

Test suite at Try it online!

How?

“WUBRG”wЀIAÆP - Main link                                   e.g. WG
“WUBRG”        - ['W','U','B','R','G']
       wЀ     - first index of sublist mapped over the input     [1,5]
          I    - incremental differences                           -4
           A   - absolute value                                     4
            ÆP - is prime?                                          0

Jonathan Allan

Posted 2017-03-13T16:54:31.207

Reputation: 67 804

7

05AB1E, 7 bytes

$Æ105¿Ö

This is a port of my Jelly answer. Takes a list of code points as input. Prints 1 for friends, 0 for foes.

Try it online!

How it works

$        Push 1 and [n, m] (the input).
 Æ       Reduce [n, m] by subtraction, pushing n - m.
  105¿   Take the GCD of n - m and 105.
      Ö  Test if 1 is divisible by the GCD (true iff the GCD is ±1).

Dennis

Posted 2017-03-13T16:54:31.207

Reputation: 196 637

6

CJam, 16 12 11 10 bytes

Golfed 4 bytes by using Mistah Figgins's algorithm

Saved 1 byte thanks to Lynn

l:m9%5%3%!

Outputs 1 for enemy colours, 0 for ally colours.

Try it online! (Or verify all test cases)

Explanation

l           e# Push a line of input as a string
 :m         e# Reduce the string by subtraction (using the ASCII values)
   9%5%3%   e# Mod by 9, then by 5, then by 3. By doing this, enemy
            e#  pairs go to 0, and allies go to 1, 2, -1, or -2.
         !  e# Boolean negation

Business Cat

Posted 2017-03-13T16:54:31.207

Reputation: 8 927

Don’t try to be too clever! l:m9%5%3%! is a byte shorter. – Lynn – 2017-03-13T19:11:27.133

@Lynn Oh wow, it is. That's kinda boring. Thanks – Business Cat – 2017-03-13T19:14:27.940

5

Java (OpenJDK 8), 28 23 bytes

-5 bytes thanks to fergusq

"WUBRGWGRBUW"::contains

Try it online!

Pavel

Posted 2017-03-13T16:54:31.207

Reputation: 8 585

3Can you do "WUBRGWGRBUW"::contains? – fergusq – 2017-03-13T17:17:23.180

5

Retina, 18 bytes

O`.
BR|BU|GR|GW|UW

Try it online!

Quite straight-forward: sorts the input and tries to match any of the sorted ally pairs against it. Unfortunately, I don't think that Retina's string-based nature allows for any of the more interesting approaches to be competitive.

As a sneak peek for the next Retina version, I'm planning to add an option which swaps regex and target string (so the current string will be used as the regex and you give it a string to check), in which case this shorter solution will work (or something along those lines):

?`WUBRGWGRBUW

Martin Ender

Posted 2017-03-13T16:54:31.207

Reputation: 184 808

4

Brachylog, 10 bytes

A straightforward solution, no tricks involved.

p~s"WUBRGW

Try it online!

Explanation

p               A permutation of the input
 ~s             is a substring of
   "WUBRGW      this string

Leo

Posted 2017-03-13T16:54:31.207

Reputation: 8 482

4

Jelly, 6 bytes

ạ:3%3Ḃ

For completeness's sake. Takes two code points as argument. Yields 0 for friends, 1 for foes.

Try it online!

Background

Let n and m be the code points of two input characters. By taking |n - m|, we need to concern ourselves only with all 2-combinations of characters. The following table shows all 2-combinations of characters the the corresponding absolute differences.

WU UB BR RG GW  WB UR BG RW GU
 2 19 16 11 16  21  3  5  5 14

If we divide these integers by 3, we get the following quotients.

WU UB BR RG GW  WB UR BG RW GU
 0  6  5  3  5   7  1  1  1  4

1, 4, and 7 can be mapped to 1 by taking the results modulo 3.

WU UB BR RG GW  WB UR BG RW GU
 0  0  2  0  2   1  1  1  1  1

Now we just have to look at the parity.

How it works

ạ:3%3Ḃ  Main link. Left argument: n (code point). Right argument: m (code point)

ạ       Absolute difference; yield |n - m|.
 :3     Integer division by 3, yielding |n - m| / 3.
   %3   Modulo 3, yielding |n - m| / 3 % 3.
     Ḃ  Parity bit; yield |n - m| / 3 % 3 & 1.

Dennis

Posted 2017-03-13T16:54:31.207

Reputation: 196 637

4

Cubix, 11 bytes

A Cubix implementation of Arnauld's solution.

U%O@A*'g%2W

Usage

Input the two characters, and it outputs 0 for friends and 1 for foes. Try it here.

Explanation

The code can be expanded like this.

    U %
    O @
A * ' g % 2 W .
. . . . . . . .
    . .
    . .

The characters are executed in this order (excluding control flow):

A*'g%2%O@
A         # Read all input as character codes
 *        # Multiply the last two character codes
    %     # Modulo the result by
  'g      #     103
      %   # And modulo that by
     2    #     2
       O  # Output the result ...
        @ # ... and terminate

Luke

Posted 2017-03-13T16:54:31.207

Reputation: 4 675

3

Python 2, 26 bytes

lambda a:a in"GWUBRGRBUWG"

Try it online!

James

Posted 2017-03-13T16:54:31.207

Reputation: 54 537

2

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!

Anthony Pham

Posted 2017-03-13T16:54:31.207

Reputation: 1 911

2

AWK, 23 Bytes

{$0="WUBRGWGRBUW"~$1}1

Example usage: awk '{$0="WUBRGWGRBUW"~$1}1' <<< UB

This prints 1 if the pair is a friend, 0 otherwise. I wanted to do something clever, but everything I thought of would be longer.

Robert Benson

Posted 2017-03-13T16:54:31.207

Reputation: 1 339

2

Jelly, 12 bytes

“WUBRGW”ŒBẇ@

Outputs 1 for allies, 0 for enemies.

Try it online!

Explanation

“WUBRGW”ŒBẇ@   Main link

“WUBRGW”       The string "WUBRGW"
        ŒB     Bounce; yields "WUBRGWGRBUW"
          ẇ@   Check if the input exists in that string

Business Cat

Posted 2017-03-13T16:54:31.207

Reputation: 8 927

2

Ruby, 28 bytes

Outputs true for friend, false for foe:

p'WUBRGWGRBUW'.include?$**''

The ungolfed version isn't much different:

p 'WUBRGWGRBUW'.include?(ARGV.join(''))

Sculper

Posted 2017-03-13T16:54:31.207

Reputation: 191

2

05AB1E, 7 bytes

Adaptation of the mod-trick from Jonathan's Jelly answer

Æ451bsè

Try it online! or as a Test suite

Explanation

 Æ        # reduced subtraction
  451b    # 451 to binary (111000011)
      sè  # index into this with the result of the reduced subtraction

Emigna

Posted 2017-03-13T16:54:31.207

Reputation: 50 798

2

///, 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.

Comrade SparklePony

Posted 2017-03-13T16:54:31.207

Reputation: 5 784

Ah, okay. Didn't know about that. – Rɪᴋᴇʀ – 2017-03-14T15:29:01.363

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/. – Ørjan Johansen – 2017-03-16T04:47:58.337

@ØrjanJohansen I made the edit, is that correct? Also, is there an online interpreter for itflabtijtslwi? I could not find one. – Comrade SparklePony – 2017-03-16T13:48:07.033

Try it online! Stripped my Perl one into a TIO header/footer. Still large for comments. :( – Ørjan Johansen – 2017-03-16T15:02:21.673

@ØrjanJohansen Thank you very much. If you don't mind, I'll put that in my answer. – Comrade SparklePony – 2017-03-16T15:05:21.723

1Sure. I just added the TIO hack to the Esolang wiki to make it official :) – Ørjan Johansen – 2017-03-16T15:10:19.193

2

GolfScript, 7 bytes

~*51%9>

Takes two code points as input.

Try it online! (Test suite which converts the input format for convenience.)

A GolfScript port of my CJam answer (which technically, is a CJam port of the result of my GolfScript brute forcer... uhhh...).

However, since GolfScript gets modulo with negative inputs right, there's a fun alternative solution at the same byte count which uses 4 for foes instead of 1:

~-)9%4&

Try it online!

xy   x    y    x-y    +1  %9  &4

WU   87   85     2     3   3   0
UB   85   66    19    20   2   0
BR   66   82   -16   -15   3   0
RG   82   71    11    12   3   0
GW   71   87   -16   -15   3   0
WB   87   66    21    22   4   4
UR   85   82     3     4   4   4
BG   66   71    -5    -4   5   4
RW   82   87    -5    -4   5   4
GU   71   85   -14   -13   5   4

Martin Ender

Posted 2017-03-13T16:54:31.207

Reputation: 184 808

2

Java 7, 38 bytes

int b(int a,int b){return(a-b)%9%5%3;}

Port from @Mistah Figgins' Befunge-98 answer is the shortest in Java 7 from the answers posted so far.
As for the others:

39 bytes: Port from @Arnauld's JavaScript (ES6) answer.

int a(int a,int b){return a*b%24%11%2;}

39 bytes: Port from @MartinEnder's CJam answer

Object e(int a,int b){return a*b%51>9;}

47 bytes: Port from @Steadybox' C answer

Object d(int a,int b){return(a=a*b%18)>7|a==3;}

52 bytes: Port from @Lynn's Python 2 answer

Object c(String s){return"WUBRGWGRBUW".contains(s);}

NOTE: Skipped answers which uses primes / palindromes and alike, because those are nowhere near short in Java. ;)
TODO: Coming up with my own answer.. Although I doubt it's shorter than most of these.

Try all here.


EDIT: Ok, came up with something myself that isn't too bad:

50 bytes:

Object c(int a,int b){return(a=a*b%18)>3&a<7|a<1;}

Explanation:

ab  a   b   a*b     %18

WU  87  85  7395    15
UB  85  66  5610    12
BR  66  82  5412    12
RG  82  71  5822    8
GW  71  87  6177    3
UW  85  87  7395    15
BU  66  85  5610    12
RB  82  66  5412    12
GR  71  82  5822    8
WG  87  71  6177    3

WB  87  66  5742    0
UR  85  82  6970    4
BG  66  71  4686    6
RW  82  87  7134    6
GU  71  85  6035    5
BW  66  87  5742    0
RU  82  85  6970    4
GB  71  66  4686    6
WR  87  82  7134    6
UG  85  71  6035    5

All enemies are either in the range 4-6 (inclusive) or 0.
EDIT2: Hmm.. I just noticed it's very similar to @Steadybox' answer.. :(

Kevin Cruijssen

Posted 2017-03-13T16:54:31.207

Reputation: 67 575

2

PHP, 31 bytes

echo!strstr(WBGURWRUGBW,$argn);

Run with echo AB | php -nR '<code>, where A and B are the two colors.

strtr returns the string from the position where the input is found;
with WBGURWRUGBW as haystack this returns a truthy string if the colors are foes; empty string if not.

! turns the truthy string to false, resulting in empty output
and the empty string to true, resulting in output 1.

Titus

Posted 2017-03-13T16:54:31.207

Reputation: 13 814

2

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.

Nitrodon

Posted 2017-03-13T16:54:31.207

Reputation: 9 181

1

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ß.

AdmBorkBork

Posted 2017-03-13T16:54:31.207

Reputation: 41 581

1

Batch, 62 bytes

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

Outputs 1 for foes, nothing for friends.

Neil

Posted 2017-03-13T16:54:31.207

Reputation: 95 035

1

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

Jörg Hülsermann

Posted 2017-03-13T16:54:31.207

Reputation: 13 026

Oh well ... stolen arithmetics: echo ord($argn)*ord($argn[1])%51<9; is another 9 bytes shorter (35 bytes). – Titus – 2017-03-15T04:27:22.323

1

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;
  }
}

user18932

Posted 2017-03-13T16:54:31.207

Reputation:

"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. ;) – Martin Ender – 2017-03-14T08:08:59.703

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. – Olivier Grégoire – 2017-03-16T09:59:32.193

Finally, you counted 1 byte too much: your answer is 16 bytes, but you say it's 17. – Olivier Grégoire – 2017-03-16T10:06:17.573

@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? – None – 2017-03-16T13:28:48.390

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;. – Olivier Grégoire – 2017-03-16T13:45:42.633

@OlivierGrégoire thanks, got it. – None – 2017-03-16T14:04:19.793

1

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

Rohan Jhunjhunwala

Posted 2017-03-13T16:54:31.207

Reputation: 2 569

Let us continue this discussion in chat.

– Rohan Jhunjhunwala – 2017-03-14T15:12:26.343

1

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

mtraceur

Posted 2017-03-13T16:54:31.207

Reputation: 111

1

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).

L3viathan

Posted 2017-03-13T16:54:31.207

Reputation: 3 151

1

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

Jo King

Posted 2017-03-13T16:54:31.207

Reputation: 38 234

1

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

Kevin Cruijssen

Posted 2017-03-13T16:54:31.207

Reputation: 67 575

0

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)

Mike Bufardeci

Posted 2017-03-13T16:54:31.207

Reputation: 1 680

0

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.

Mwr247

Posted 2017-03-13T16:54:31.207

Reputation: 3 494

0

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...

steenbergh

Posted 2017-03-13T16:54:31.207

Reputation: 7 772

0

C#, 37 Bytes

(string s)=>"GWUBRGRBUWG".Contains(s)

Snowfire

Posted 2017-03-13T16:54:31.207

Reputation: 181

0

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.

Xcali

Posted 2017-03-13T16:54:31.207

Reputation: 7 671