16
\$\begingroup\$

Two random numbers A and B have been generated to be either 1, 2, or 3

your job is to randomly pick a third number C that can also be 1, 2 or 3. But, C cannot equal A or B.

  • A can equal B.
  • If A = B, then C has only two numbers left it can be.
  • If A ≠ B, C has only one number it can be.
  • Assume A and B have already been chosen for you

This is how A and B would be created in Python

A = random.randrange(1,4)
B = random.randrange(1,4)

Assume this is already in your code.

This is the shortest I've come up with in Python

while True:
    C = random.randrange(1,4)
    if C != A and C != B:
        break

Here are some acceptable values for A, B and C.

  • 1,2,3
  • 1,1,2
  • 2,3,1
  • 3,3,2

Here are some unacceptable values for A, B and C.

  • 1,2,1
  • 2,3,3
  • 1,1,1
  • 3,2,3
\$\endgroup\$
12
  • 2
    \$\begingroup\$ So if A and B are given, they aren't actually random as far as my program/function is concerned, right? Also what do you mean by "general code"? Are you actually looking for a solution you can use in a project of yours? In that case, I wouldn't look to code-golf for help - the code is going to be absolutely unusable in production. The entire point of code-golf is to abuse language-specific features to get the code size as far down as possible. \$\endgroup\$ Jul 4, 2014 at 17:56
  • \$\begingroup\$ I was using this for a project and have already got a long answer, but I am asking this because I thought it was interesting problem that the community would enjoy. And I put general code because I find it more interesting when someone used more logical thinking to get an answer rather than vast knowledge of some language-specific features, but if code-golf is to abuse these, then I will remove that last line. \$\endgroup\$ Jul 4, 2014 at 18:00
  • \$\begingroup\$ Well assume A and B can equal either 1, 2 or 3, so right your code to anticipate all of the possibilities. \$\endgroup\$ Jul 4, 2014 at 18:02
  • 2
    \$\begingroup\$ I don't understand. Is there something I'm missing or does C = (A!=B ? 6-A-B : (!(A-1) ? 2 : 1)) work? Also your solution is highly inefficient as it wastes time looping and possibly could take an infinite amount of time to run. Also, import random counts in byte size... \$\endgroup\$
    – DankMemes
    Jul 4, 2014 at 18:14
  • 3
    \$\begingroup\$ So you want us to write a Monty Hall simulator? ;-) \$\endgroup\$ Jul 5, 2014 at 2:01

31 Answers 31

18
\$\begingroup\$

Ruby, 22 characters

([1,2,3]-[A,B]).sample

Still not sure if I understood the question correctly ...

\$\endgroup\$
12
\$\begingroup\$

C,26

a-b?6-a-b:(rand()%2+a)%3+1

If I've understood the question correctly:

If a and b are different, there is no random. the answer must be the only one of 1,2,3 that is unused: 6-a-b.

IF a and b are the same there are 2 choices:

a=b=           1 2 3
            return value    
rand()%2=0     2 3 1
rand()%2=1     3 1 2
\$\endgroup\$
5
\$\begingroup\$

Befunge (156 89 85 74)

Okay, this is terrible, I know. But it's my first Befunge attempt ever, so I'm still pretty happy that it even works. I'm sure there's a much, much better solution.

<v1p90&p80&
<<@.g70_v#-g70_v#-g70g90g80p70
  v     <      <
^1?v
^3<2
^  <
\$\endgroup\$
3
  • 1
    \$\begingroup\$ On my phone right now.. Not sure if some rows shifted a bit accidentally. I'll check it when I'm home. \$\endgroup\$
    – Ingo Bürk
    Jul 5, 2014 at 15:06
  • \$\begingroup\$ Looks good to me. Much better than my 99 bytes attempt. I hope you're having fun with befunge. \$\endgroup\$
    – AndoDaan
    Jul 5, 2014 at 16:33
  • \$\begingroup\$ Yeah, the mobile version doesn't seem to be monospaced. Befunge is quite fun, but I wish there'd be a decent Befunge-98 interpreter (I couldn't find any… /edit: rcfunge seems to work) \$\endgroup\$
    – Ingo Bürk
    Jul 5, 2014 at 17:47
3
\$\begingroup\$

Python, 14 characters

I tried it for every 9 possible cases and it seems to work fine!

C=A^B or A^1|2

(edit): As edc65 pointed out, this isn't valid since it's not random... I missed that part of the question and I feel stupid right now.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ Not random at all \$\endgroup\$
    – edc65
    Jul 5, 2014 at 6:33
  • \$\begingroup\$ Still, +1 for the admission \$\endgroup\$
    – Mr Lister
    Jul 5, 2014 at 15:01
3
\$\begingroup\$

GolfScript, 13 chars

~0]4,^.,rand=

This is a complete GolfScript program that reads two whitespace-separated numbers (each assumed to be either 1, 2, or 3) from standard input, and outputs a random number from the set {1, 2, 3} that does not equal any of the input numbers.

Try it online. (Note: the link is to the previous version; I'm on a mobile device and can't fix it.)

Here's a commented version of the program:

~         # eval the input, pushing the input numbers onto the stack
0         # push the number 0 onto the stack
]         # collect all the numbers on the stack into an array
4,        # create another array containing the numbers 0, 1, 2 and 3
^         # xor the arrays (i.e. take their symmetric set difference)
.,rand=   # choose a random element from the array

If you'd prefer a named function that takes the two numbers as arguments on the stack, that takes a few more chars:

{[\0]4,^.,rand=}:f;

The actual body of the function is only one char longer than the stand-alone code (because we need the [ to make sure we consume only two arguments), but the overhead of wrapping the code in a block and assigning it to a symbol takes five more chars, for a total of 19.

Alternatively, if you literally have the two numbers assigned into the variables A and B, and want the third number assigned to C, that can also be done in 19 chars:

4,[0A B]^.,rand=:C;

(If leaving the third number on the stack instead is acceptable, you can leave the :C; off the end.)

Ps. Thanks for the suggestion to use ^, Howard.

\$\endgroup\$
1
  • \$\begingroup\$ Instead of \- you can use ^. \$\endgroup\$
    – Howard
    Jul 5, 2014 at 13:25
3
\$\begingroup\$

Python - 35

C=random.sample({1,2,3}-{A,B},1)[0]

Assumes random is imported, which seems to be specified in the question.

PYG - 25

C=RSm({1,2,3}-{A,B},1)[0]
\$\endgroup\$
2
\$\begingroup\$

Befunge - 99 bytes

&:01p&:11p-!!#v_v
   @,g2+g11g10< "
   321 vv*2g<"v ^
 2v v v 5v*2^10<"
 v?v?v?vp5     ^<
 2 3 1 2<        
 > > > >.@       

Not very impressive.

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

PowerShell, 21

1..3-ne$A-ne$B|random

Very straightforward. Abusing the fact that comparison operators act differently with an array as their left operand.

\$\endgroup\$
1
  • \$\begingroup\$ Nice tip about the comparison operators. Makes me want to look at some of my old scripts and see if there are places it can be used. Particularly, this reminds me of part of the Monty Hall simulator. \$\endgroup\$
    – Iszi
    Jul 8, 2014 at 19:54
1
\$\begingroup\$

Mathematica, 37 bytes

RandomChoice@DeleteCases[{1,2,3},a|b]

Basically the same as the Ruby answer, but considerably longer thanks to Mathematica's function names. I'm using lower-case variables, because upper-case names might clash with built-ins (they don't, in this case, but you simply don't do it in Mathematica).

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

R, 42 chars

x=c(1,1,1);x[c(A,B)]=0;C=sample(1:3,1,p=x)

Vector x is the vector of probability weights for obtaining the elements of the vector being sampled. It is set to 1 for each at first, then elements corresponding to A and B are set to 0, hence they have no chance of being picked.

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

Rebol - 40 chars

random/only difference[1 2 3]reduce[A B]
\$\endgroup\$
1
\$\begingroup\$

CJam - 12

4,[AB0]-mr0=

This assumes the variables A and B have already been set, according to the question.

You can try it at http://cjam.aditsu.net/

To test it with random numbers, use:

"A="3mr):A", B="3mr):B", C="
4,[AB0]-mr0=

To test it with specific values, use (for example):

"A="1:A", B="1:B", C="
4,[AB0]-mr0=

Explanation:

4, creates the array [0 1 2 3]
[AB0]- removes the numbers A, B and 0 from the array
mr shuffles the remaining array
0= takes the first element

In a future CJam version this program will be 2 bytes shorter :)

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

C 67

int C(int a,int b){int c=0;while(c!=a&&c!=b)c=rand()%3+1;return c;}
\$\endgroup\$
1
\$\begingroup\$

JS, 35

inspired by Brandon Anzaldi's answer

A=1; // init
B=3; // init
do{C=1+new Date%3}while(C==A||C==B) // 35b
\$\endgroup\$
1
\$\begingroup\$

Pyth, 5 bytes

O.-S3

Try it online!

O.-S3
O.-S3Q - Implicitly read input
   S3  - Create range [1, 2, 3]
 .-    - Subtract input elements from the range
O      - Select a random element.
\$\endgroup\$
1
\$\begingroup\$

Arn, 9 bytes

╚<<ٌԓÂj

Try it!

Explained

Unpacked: ?.$v{!&v}~3

?.          Random entry in
  $           Filtered list
    v{          With block; entry named v
      !           Boolean NOT
          _           Variable ≡ STDIN; implied
        &           Contains (implicit casting to array)
          v           Variable `v`
    }            End block
    ~           On one-range to
      3           Literal three
\$\endgroup\$
0
\$\begingroup\$

Julia, 32 or 56 depending on the rules

julia> r()=rand(1:3);f(x...)=(i=r();i in x?f(x...):i)
julia> f(r(),r())

32 if I don't need to generate a and b.

\$\endgroup\$
1
  • \$\begingroup\$ The question says "assume A and B have already been chosen for you". \$\endgroup\$ Jul 6, 2014 at 14:20
0
\$\begingroup\$

JS, 43

for(C=0;~[0,A,B].indexOf(C);)C=1+new Date%3
\$\endgroup\$
2
  • \$\begingroup\$ Won't run. You might want to define A and B first. \$\endgroup\$
    – Spedwards
    Jul 6, 2014 at 7:34
  • \$\begingroup\$ well, the question says: "Assume A and B have already been chosen for you". So you should run "A=1+new Date%3;B=1+new Date%3" first. \$\endgroup\$
    – xem
    Jul 6, 2014 at 7:54
0
\$\begingroup\$

Java - 126 123 83 85 (using the clever c=6-a-b)

int c;if(a==b){int r=(int)(Math.random()*2);c=a==1?r+2:a==2?2*r+1:r+1;}else{c=6-a-b;}

Full version:

public void test(int a, int b) {
    int c;
    if (a == b) {
        // Random 0 or 1.
        int r = (int)Math.random()*2;
        c = // 1 -> 2 or 3
                a == 1 ? r + 2
                // 2 -> 1 or 3
                : a == 2 ? 2 * r + 1
                // 3 -> 1 or 2
                : r + 1;
    } else {
        // Whichever is not taken.
        //int[][] r = {{0, 3, 2}, {3, 0, 1}, {2, 1, 0}};
        //c = r[a - 1][b - 1];
        // Using @steveverrill's clever
        c = 6 - a - b;
    }
    System.out.println("a=" + a + " b=" + b + " c=" + c);
}
\$\endgroup\$
3
  • \$\begingroup\$ But 6-a-b is not random, is it? :) \$\endgroup\$
    – xem
    Jul 6, 2014 at 8:02
  • 1
    \$\begingroup\$ @xem - No - but it only uses 6-a-b when there is no other choice, both the other two are taken. It is a clever way of picking the unselected number from 1, 2, 3. 6-1-2 = 3, 6-1-3=2, 6-2-3=1 so for each non-equal a,b 6-a-b picks the third one. Clever eh? The only time you can use random is when a==b. \$\endgroup\$ Jul 6, 2014 at 19:34
  • \$\begingroup\$ oh, great. good job then. \$\endgroup\$
    – xem
    Jul 7, 2014 at 7:38
0
\$\begingroup\$

R, 24 characters

Initialize with

a = sample(1:3,1)
b = sample(1:3,1)

Then

n=1:3;n[!n%in%c(a,b)][1]

Or just n=1:3;n[!n%in%c(a,b)] but then you return both numbers.

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

R, 31 characters

sample(rep((1:3)[-c(A,B)],2),1)

If you do sample(x) in R, then it is interpreted as a random sample from 1:x. Repeating the vector (1:3)[-c(A,B)] twice is one way of stopping this from happening.

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

Javascript - 76

r=(y,z)=>Math.floor(Math.random()*(z-y+1)+y);a=b=r(1,3);while(c==a)c=r(1,3);
\$\endgroup\$
7
  • 1
    \$\begingroup\$ Math.floor can be replaced by ~~. You could also say r=(y,z)=>y+New Date(z-y). Also, A and B are not meant to be equal, and you don't have to count their initialization in your score. \$\endgroup\$
    – xem
    Jul 6, 2014 at 8:00
  • \$\begingroup\$ @xem A and B are meant to be random. The rules say that they can be equal. Also, not sure about ES6 but y+New Date(z-y) is a SyntaxError \$\endgroup\$
    – Spedwards
    Jul 6, 2014 at 8:33
  • \$\begingroup\$ @xem y+new Date(z-y) on the other hand reports new Date() string with y appended. \$\endgroup\$
    – Spedwards
    Jul 6, 2014 at 8:35
  • \$\begingroup\$ sorry for the typo, I meant y+new Date%(z-y) ... or (z-y+1) depending on the params. \$\endgroup\$
    – xem
    Jul 6, 2014 at 9:52
  • \$\begingroup\$ and my remark about A and B equal was about "a=b=r(1,3);". If you do that a is always equal to b, but that's not what the rules ask. They ask for A and B random. They can be equal but not necessarily \$\endgroup\$
    – xem
    Jul 6, 2014 at 9:55
0
\$\begingroup\$

C - 38

main(c){for(;c==a|c==b;c=rand()%2+1);}
\$\endgroup\$
0
\$\begingroup\$

Java, 264 bytes

Random r = new Random();ArrayList<Integer> s = new ArrayList<>();ArrayList<Integer> q = new ArrayList<>();for(int i=0; i<n; i++) s.add(r.nextInt(k));q.add(s.get(r.nextInt(n)));q.add(s.get(r.nextInt(n)));int x;do{x = s.get(r.nextInt()); }while(!q.contains(x));

This code generates n different random numbers from 0 to k.

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

J (21 19: too long for my liking)

({~?@#)(>:i.3)-.A,B

Are there any J wizards around to help remove that variable assignment? It's only 2 chars shorter...

Or, if it doesn't have to be random, you could do with this:

{:(i.4)-.A,B

12 chars.

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

Golfscript, 13 Characters

~]4,^.,rand)=
\$\endgroup\$
0
\$\begingroup\$

JavaScript - 41 (up to 46) 37 35 34 30

Updated:

Managed to get it down to 30 chars by modifying it, inspired by stevevarrill's answer in C.

C=A-B?6-A-B:1+(A+new Date%2)%3


Thank you nyuszika7h for getting me down to 34~:

C=A;while(C==A|C==B)C=1+new Date%3

Borrowing from xem's answer to at least fall on par with him:

C=A;while(C==A||C==B)C=1+new Date%3

Thanks for reminding me that 1+new Date%3 === (new Date%3)+1!

Previous Solution:

C=A;while(C==A||C==B)C=(new Date%3)+1

Ensure conditions of while() are satisfied, and loop through until they're not.


Other solution:

C=A!=B?6-A-B:A%2!=0?4-B:new Date%2!=1?3:1;

This assumes that C has already been declared OR that the JavaScript interpreter can handle undeclared variables.

However, if the JS interpreter can handle EOL without a semicolon, it could be bumped down to 41.

C=A!=B?6-A-B:A%2!=0?4-B:new Date%2!=1?3:1

If C hasn't been declared, and there is no error correction for it, that will bring the tally up to 46 characters.

var C=A!=B?6-A-B:A%2!=0?4-B:new Date%2!=1?3:1;

Test Program:

var iterations = 100;

for(var i = 0;i<iterations;i++) {
    var A = Math.floor(Math.random() * 3) + 1;
    var B = Math.floor(Math.random() * 3) + 1;
    C=A!=B?6-A-B:A%2!=0?4-B:new Date%2!=1?3:1
    if (C === A || C === B || C > 3 || C < 1) {
        console.log('FAILURE!');
        console.log(A + ',' + B + ',' + C)
        return;
    }
    console.log(A+','+B+','+C);
}
\$\endgroup\$
4
  • \$\begingroup\$ great! I made a 35b answer based on this, but using a do-while loop ;) \$\endgroup\$
    – xem
    Jul 6, 2014 at 11:49
  • \$\begingroup\$ You should be able to use | instead of ||. \$\endgroup\$ Jul 6, 2014 at 14:16
  • \$\begingroup\$ Save 1 byte with a for loop: for(C=A;C==A|C==B;)C=1+new Date%3 \$\endgroup\$ Jul 7, 2014 at 15:50
  • \$\begingroup\$ I'd just like to thank everyone for their help :) \$\endgroup\$ Aug 9, 2014 at 5:08
0
\$\begingroup\$

Befunge-98 (57 bytes)

This code assumes the numbers will be input on stdin. It will pick a random number if both of the first numbers are the same until it is different, otherwise it will choose the last available number.

6&::11p&:12pw>   ?1  >#<:11g-!_.@
     @.-g21-<>3;#[2#;^
\$\endgroup\$
0
\$\begingroup\$

Jelly, 5 bytes

3Rḟ⁸X

Try it online!

This takes [A, B] as input, as Jelly doesn't have the concept of variables

How it works

3Rḟ⁸X - Main link. Takes [A, B] on the left
3R    - Yield [1, 2, 3]
   ⁸  - Yield [A, B]
  ḟ   - Remove [A, B] from [1, 2, 3]
    X - Randomly select an element from the remaining list
\$\endgroup\$
0
\$\begingroup\$

Japt, 7 bytes

3õ kU ö

Try it here

\$\endgroup\$

Your Answer

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

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