# Randomly pick one number that is different than two other random numbers

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.

• And Yes, A can equal B.
• If A = B, then C has only two numbers left it can be.
• If A does not equal 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)


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


This is what A, B and C can equal.

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

This is what A, B and C can't equal

• 1,2,1
• 2,3,3
• 1,1,1
• 3,2,3
• 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. – Martin Ender Jul 4 '14 at 17:56
• 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. – tysonsmiths Jul 4 '14 at 18:00
• Well assume A and B can equal either 1, 2 or 3, so right your code to anticipate all of the possibilities. – tysonsmiths Jul 4 '14 at 18:02
• 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... – DankMemes Jul 4 '14 at 18:14
• So you want us to write a Monty Hall simulator? ;-) – Ilmari Karonen Jul 5 '14 at 2:01

## Ruby, 22 characters

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


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

# 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


## Befunge (1568985 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
^  <

• On my phone right now.. Not sure if some rows shifted a bit accidentally. I'll check it when I'm home. – Ingo Bürk Jul 5 '14 at 15:06
• Looks good to me. Much better than my 99 bytes attempt. I hope you're having fun with befunge. – AndoDaan Jul 5 '14 at 16:33
• 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) – Ingo Bürk Jul 5 '14 at 17:47

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

• Instead of \- you can use ^. – Howard Jul 5 '14 at 13:25

# 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]


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.

• Not random at all – edc65 Jul 5 '14 at 6:33
• Still, +1 for the admission – Mr Lister Jul 5 '14 at 15:01

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

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

• 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. – Iszi Jul 8 '14 at 19:54

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

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

# Rebol - 40 chars

random/only difference[1 2 3]reduce[A B]


# 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 :)

## C 67

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


## JS, 35

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


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

• The question says "assume A and B have already been chosen for you". – nyuszika7h Jul 6 '14 at 14:20

## JS, 43

for(C=0;~[0,A,B].indexOf(C);)C=1+new Date%3

• Won't run. You might want to define A and B first. – Spedwards Jul 6 '14 at 7:34
• 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. – xem Jul 6 '14 at 7:54

# TI-BASIC, 23

Lbl 1:If C=A+B=A:Goto 1

• Does not work due to order of operations; additionally you never actually generated the random number. – lirtosiast May 20 '15 at 1:11

# Java - 12612383 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);
}

• But 6-a-b is not random, is it? :) – xem Jul 6 '14 at 8:02
• @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. – OldCurmudgeon Jul 6 '14 at 19:34
• oh, great. good job then. – xem Jul 7 '14 at 7:38

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

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.

# 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);

• 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. – xem Jul 6 '14 at 8:00
• @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 – Spedwards Jul 6 '14 at 8:33
• @xem y+new Date(z-y) on the other hand reports new Date() string with y appended. – Spedwards Jul 6 '14 at 8:35
• sorry for the typo, I meant y+new Date%(z-y) ... or (z-y+1) depending on the params. – xem Jul 6 '14 at 9:52
• 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 – xem Jul 6 '14 at 9:55

# C - 38

main(c){for(;c==a|c==b;c=rand()%2+1);}


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

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

# Golfscript, 13 Characters

~]4,^.,rand)=


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

• great! I made a 35b answer based on this, but using a do-while loop ;) – xem Jul 6 '14 at 11:49
• You should be able to use | instead of ||. – nyuszika7h Jul 6 '14 at 14:16
• Save 1 byte with a for loop: for(C=A;C==A|C==B;)C=1+new Date%3 – openorclose Jul 7 '14 at 15:50
• I'd just like to thank everyone for their help :) – Brandon Anzaldi Aug 9 '14 at 5:08

## 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#;^


Python, 54 41 characters

Quite long answer in Python but I like list comprehension, so I decided to post this here

// [0] means it is the first element of

C=[i for i in[1,2,3]if not(i in(A,B))][0]

• How is this random? – user80551 Jul 4 '14 at 18:46
• It isn't, sorry... – Caridorc Jul 4 '14 at 18:49
• @user80551 does it need to be? – John Dvorak Jul 6 '14 at 1:43
• @JanDvorak Yes: "your job is to randomly pick a third number..." (I think this needs some more emphasis in the question, as many have gotten it wrong) – daniero Jul 6 '14 at 2:08