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

14

3

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)

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

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

tysonsmiths

Posted 2014-07-04T17:53:33.867

Reputation: 351

1So 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 – 2014-07-04T17:56:03.413

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 – 2014-07-04T18:00:37.407

Well assume A and B can equal either 1, 2 or 3, so right your code to anticipate all of the possibilities. – tysonsmiths – 2014-07-04T18:02:23.890

1I 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 – 2014-07-04T18:14:39.020

I edited my question to add clarity – tysonsmiths – 2014-07-04T18:18:33.173

You can do random.randint(1,3) to make it shorter. – user80551 – 2014-07-04T18:20:17.353

If A,B=random.randrange(1,4),random.randrange(1,4) is already in the code, can I assume that import random is also there or will it count towards my byte-count? – user80551 – 2014-07-04T18:23:21.213

You can assume that's already in there. Assume A and B are variables already created. – tysonsmiths – 2014-07-04T18:25:06.723

Whoops I made a mistake in my above comment. That code should be C=A!=B?6-A-B:!(A-1)?2:!(A-2)?3:2 (32 bytes by the way) – DankMemes – 2014-07-04T18:40:02.990

3

So you want us to write a Monty Hall simulator? ;-)

– Ilmari Karonen – 2014-07-05T02:01:17.317

@IlmariKaronen I totally missed the similarity to Monty Hall! it is indeed equivalent to the choice the host makes once he has the player's first guess (since he already knows where the prize is.) However it doesn't simulate a) the placement of the prize or b) the choices made by the player. I don't think this is a duplicate of the other Monty Hall questions. – Level River St – 2014-07-05T10:05:29.647

Does it have to be a complete program or is a snippet enough? (e.g. leaving out main() in C) – nyuszika7h – 2014-07-06T14:12:35.540

Answers

17

Ruby, 22 characters

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

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

Ventero

Posted 2014-07-04T17:53:33.867

Reputation: 9 842

12

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

Level River St

Posted 2014-07-04T17:53:33.867

Reputation: 22 049

5

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

Ingo Bürk

Posted 2014-07-04T17:53:33.867

Reputation: 2 674

1On my phone right now.. Not sure if some rows shifted a bit accidentally. I'll check it when I'm home. – Ingo Bürk – 2014-07-05T15:06:08.820

Looks good to me. Much better than my 99 bytes attempt. I hope you're having fun with befunge. – AndoDaan – 2014-07-05T16:33:21.280

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 – 2014-07-05T17:47:44.007

3

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]

Ian D. Scott

Posted 2014-07-04T17:53:33.867

Reputation: 1 841

3

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.

Ilmari Karonen

Posted 2014-07-04T17:53:33.867

Reputation: 19 513

Instead of \- you can use ^. – Howard – 2014-07-05T13:25:50.153

2

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.

SimonD

Posted 2014-07-04T17:53:33.867

Reputation: 46

3Not random at all – edc65 – 2014-07-05T06:33:51.457

Still, +1 for the admission – Mr Lister – 2014-07-05T15:01:16.617

2

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.

AndoDaan

Posted 2014-07-04T17:53:33.867

Reputation: 2 232

2

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.

Joey

Posted 2014-07-04T17:53:33.867

Reputation: 12 260

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 – 2014-07-08T19:54:36.910

1

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

Martin Ender

Posted 2014-07-04T17:53:33.867

Reputation: 184 808

1

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.

plannapus

Posted 2014-07-04T17:53:33.867

Reputation: 8 610

1

Rebol - 40 chars

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

draegtun

Posted 2014-07-04T17:53:33.867

Reputation: 1 592

1

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

aditsu quit because SE is EVIL

Posted 2014-07-04T17:53:33.867

Reputation: 22 326

1

C 67

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

bacchusbeale

Posted 2014-07-04T17:53:33.867

Reputation: 1 235

1

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

xem

Posted 2014-07-04T17:53:33.867

Reputation: 5 523

0

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.

gggg

Posted 2014-07-04T17:53:33.867

Reputation: 1 715

The question says "assume A and B have already been chosen for you". – nyuszika7h – 2014-07-06T14:20:24.470

0

TI-BASIC, 23

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

Timtech

Posted 2014-07-04T17:53:33.867

Reputation: 12 038

Does not work due to order of operations; additionally you never actually generated the random number. – lirtosiast – 2015-05-20T01:11:17.537

0

JS, 43

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

xem

Posted 2014-07-04T17:53:33.867

Reputation: 5 523

Won't run. You might want to define A and B first. – Spedwards – 2014-07-06T07:34:56.970

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 – 2014-07-06T07:54:28.350

0

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.

ɐɔıʇǝɥʇuʎs

Posted 2014-07-04T17:53:33.867

Reputation: 4 449

0

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

OldCurmudgeon

Posted 2014-07-04T17:53:33.867

Reputation: 239

But 6-a-b is not random, is it? :) – xem – 2014-07-06T08:02:22.740

1@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 – 2014-07-06T19:34:43.983

oh, great. good job then. – xem – 2014-07-07T07:38:08.473

0

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.

shadowtalker

Posted 2014-07-04T17:53:33.867

Reputation: 461

0

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.

Flounderer

Posted 2014-07-04T17:53:33.867

Reputation: 596

0

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

Spedwards

Posted 2014-07-04T17:53:33.867

Reputation: 159

1Math.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 – 2014-07-06T08:00:59.593

@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 – 2014-07-06T08:33:55.757

@xem y+new Date(z-y) on the other hand reports new Date() string with y appended. – Spedwards – 2014-07-06T08:35:58.797

sorry for the typo, I meant y+new Date%(z-y) ... or (z-y+1) depending on the params. – xem – 2014-07-06T09:52:23.917

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 – 2014-07-06T09:55:41.440

@xem A and B are random, just not separately set and the rules don't state that that isn't allowed. – Spedwards – 2014-07-06T10:18:24.030

Try to read the rules again. It's not that dificult. "Assume A and B are already choosed. If A= B... If A does not equal B..." – edc65 – 2014-07-06T16:27:38.897

0

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

Brandon Anzaldi

Posted 2014-07-04T17:53:33.867

Reputation: 171

great! I made a 35b answer based on this, but using a do-while loop ;) – xem – 2014-07-06T11:49:14.110

You should be able to use | instead of ||. – nyuszika7h – 2014-07-06T14:16:33.510

Save 1 byte with a for loop: for(C=A;C==A|C==B;)C=1+new Date%3 – openorclose – 2014-07-07T15:50:35.850

I'd just like to thank everyone for their help :) – Brandon Anzaldi – 2014-08-09T05:08:58.963

0

C - 38

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

nyuszika7h

Posted 2014-07-04T17:53:33.867

Reputation: 1 624

0

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.

padawan

Posted 2014-07-04T17:53:33.867

Reputation: 294

0

Golfscript, 13 Characters

~]4,^.,rand)=

Kyle McCormick

Posted 2014-07-04T17:53:33.867

Reputation: 3 651

0

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

waylon531

Posted 2014-07-04T17:53:33.867

Reputation: 411

-3

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]

Caridorc

Posted 2014-07-04T17:53:33.867

Reputation: 2 254

How is this random? – user80551 – 2014-07-04T18:46:46.887

It isn't, sorry... – Caridorc – 2014-07-04T18:49:58.057

@user80551 does it need to be? – John Dvorak – 2014-07-06T01:43:21.503

1@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 – 2014-07-06T02:08:32.640