Random script that isn't actually random

106

17

As a little joke in the office someone wanted a script that randomly picks a name, and said person will make a round of drinks.

Let's call the people John, Jeff, Emma, Steve and Julie.

I thought it would be funny to make a script that seems random at a quick glance, but actually always gives the same person as the output (Up to you who you choose).

Highest voted answer wins after a week

And the winner is....

Paul R with (currently) 158 votes.

The answers here are great, and if anyone else has any other ideas what haven't been posted yet, please add them, I love reading through them.

TMH

Posted 2014-06-16T12:17:01.047

Reputation: 1 273

Where should the output go? :) – Knerd – 2014-06-16T12:19:55.117

Erm, I'd say print to console if your language has one, if not echo/print it. – TMH – 2014-06-16T12:21:27.543

44http://xkcd.com/221/ – AstroCB – 2014-06-16T19:30:27.830

6@AstroCB one of my favourites. Right behind bobby tables. – Cruncher – 2014-06-16T20:08:28.697

50It seems like it would be sneakier if it was random, except for never picking one person. – Brendan Long – 2014-06-16T22:52:28.287

@AstroCB that's what I thought of immediately... Still trying to find a language that implements that. It'd take the cake :P – Jwosty – 2014-06-17T03:48:51.560

6

@AstroCB this one is also fantastic: http://dilbert.com/strips/comic/2001-10-25/

– gilbertohasnofb – 2014-06-18T10:08:07.007

2

@AstroCB apparently, some large company cough - sony - cough did something similar

– iFreilicht – 2014-06-18T14:00:58.630

ObRef: The original random-not-random story of Mel, the Real Programmer.

– Miserable Variable – 2014-07-15T19:11:44.423

3I went through the first page: most answers always choose John, 2nd highest is Julie, Jeff is chosen rarely and Steve by 1. Even Ray got chosen by one but nobody chose Emma. Moral of the story: when standing in a line to decide randomly who will buy the drinks, name yourself Emma. – Miserable Variable – 2014-07-15T19:33:37.837

Answers

171

C

It's important to decide who is buying as quickly as possible, so as not to waste precious drinking time - hence C is the obvious choice in order to get maximum performance:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    const char *buyer;
    int n;

    srand(time(NULL)); // make sure we get a good random seed to make things fair !
    n = rand();
    switch (n % 5)
    {
        case 0: buyer = "John";
        case 1: buyer = "Jeff";
        case 2: buyer = "Emma";
        case 3: buyer = "Steve";
        case 4: buyer = "Julie";
    }
    printf("The person who is buying the drinks today is: %s !!!\n", buyer);
    return 0;
}

Explanation:

This would work just fine if there was a break; after each case in the switch statement. As it stands however each case "falls through" to the next one, so poor Julie always ends up buying the drinks.

Paul R

Posted 2014-06-16T12:17:01.047

Reputation: 2 893

1Damn! I knew about break statements (in C++) but still didn't realise they were missing. +1 – ghosts_in_the_code – 2016-01-27T14:57:44.023

17+1 for performance -- much faster than rolling a physical die! ;) – Jwosty – 2014-06-17T03:46:49.463

16I'm thinking about optimising it further, perhaps with SIMD or GPGPU, just to get a little more performance. ;-) – Paul R – 2014-06-17T07:12:34.493

7Absolutely real live applicable. No one would ever even question that it was an accident in the slightest. – iFreilicht – 2014-06-18T14:04:00.180

5Is it just me or is this one too obvious to spot? – Alvin Wong – 2014-06-23T11:09:17.530

1@PaulR Congratulations, you're the highest voted answer after a week :). – TMH – 2014-06-23T12:04:46.047

3@AlvinWong I didn't notice it immediately. Then again, I don't use C regularily, or any other language that descended from BCPL. – Rhymoid – 2014-06-23T12:52:02.040

164

PHP

Couldn't let this go, so here is another one:

$f = fopen('/dev/random','r');
$s = fread($f, 4);
fclose($f);

$names = ['John', 'Jeff', 'Emma', 'Steve', 'Julie'];

echo $names[$s % count($names)];

This is actually not guaranteed to produce john, but chances are very good. PHP will happily take whatever /dev/random have to offer see that it (probably) can't parse it and come up with the very reasonable number 0 instead. After all, alerting the programmer to a potential error is considered a deadly sin in PHP.

monocell

Posted 2014-06-16T12:17:01.047

Reputation: 2 551

obligatory phpsadness – clap – 2015-11-02T15:58:57.887

25You got to love PHP - and even better, it will sometimes rarely choose someone else. So if you're lucky it will just seem a little biased at first – Falco – 2014-06-16T16:18:58.500

142+1000 for "...alerting the programmer to a potential error is considered a deadly sin in PHP." – jsedano – 2014-06-16T16:51:58.807

85

Haskell

It's too transparent if it always returns the same name so try the following

import Control.Monad
import System.Exit
import Control.Concurrent
import Control.Concurrent.MVar


data Person = John | Jeff | Emma | Steve | Julie deriving (Show, Enum)

next Julie = John
next p = succ p

rotate :: MVar Person -> IO ()
rotate mp = modifyMVar_ mp (return . next) >> rotate mp

main :: IO ()
main = do
    mp <- newMVar John
    forkIO $ rotate mp
    putStrLn "Shuffling"
    readMVar mp >>= print
    exitWith ExitSuccess

Whenever you want it to be random:

[~]$ runghc prog.hs
Shuffling
Steve

[~]$ runghc prog.hs
Shuffling
Julie

And for your unfortunate target:

[~]$ runhugs prog.hs
Shuffling
John

[~]$ runhugs prog.hs
Shuffling
John

Hugs only implements cooperative multitasking, so the rotate thread will never run

monocell

Posted 2014-06-16T12:17:01.047

Reputation: 2 551

@monocell Well, technically, even a photo of a moving object can be clear. – ghosts_in_the_code – 2016-01-27T14:59:09.040

24That's diabolical! – Daenyth – 2014-06-16T17:59:04.427

8Feels like photographing a dice which has not yet stopped moving. – Vi. – 2014-06-19T08:25:08.710

1@Vi. That is a nice analogy. Luckily the use of MVars guarantee that the picture will not be blurry. :) – monocell – 2014-06-19T08:41:06.603

74

Bash - maximum simplicity

A very simple example - let's avoid any problems by doing it the textbook way. Don't forget to seed the generator from the system clock for a good result!

#!/bin/bash

names=(John Jeff Emma Steve Julie)   # Create an array with the list of names
RANDOM=$SECONDS                      # Seed the random generator with seconds since epoch
number=$((RANDOM % 5))               # Pick a number from 0 to 4
echo ${names[number]}                # Pick a name

This relies on the user not knowing what the $SECONDS builtin actually does; it returns the number of seconds since the current shell started. As it's in a script, the shell always started zero seconds ago, so the generator is always seeded with 0 and Julie always buys the beer.

Bonus:

This one stands up to scrutiny quite well; If you enter the same code on the commandline instead of in a script, it will give random results, because $SECONDS will return the length of time the user's interactive shell has been running.

Riot

Posted 2014-06-16T12:17:01.047

Reputation: 4 639

9\o/ Mean!!! Really mean!!! $SECONDS ftw! \o/ – None – 2014-06-17T17:47:18.183

What happens if you source this, instead of just executing it? Will the shebang still trigger a new shell or something? – jpmc26 – 2014-06-26T14:22:19.733

1@jpmc26: if you execute it with source then it's exactly the same as if you'd typed the commands on the commandline yourself; #!/bin/bash is a comment so it's ignored. This is true of any script. – Riot – 2014-06-26T21:57:57.853

57

C#

using System;
using System.Linq;

namespace PCCG {
    class PCCG31836 {
        public static void Main() {
            var names = new string[]{ "John", "Jeff", "Emma", "Steve", "Julie" };
            var rng = new Random();
            names.OrderBy(name => rng.Next());
            Console.WriteLine(names[0]);
        }
    }
}

This might not fool people who are familiar with the .Net API, but people who don't know it might believe that OrderBy modifies the object you call it on, and it's a plausible error for a newbie to the API to make.

Peter Taylor

Posted 2014-06-16T12:17:01.047

Reputation: 41 901

1Even if OrderBy hypothetically modified the object, would that call actually sort the list randomly? As someone unfamiliar with .NET, my first guess was that since rng.Next() is only called once, the array would be sorted by a constant, resulting in no change (or a change that depends only on the sorting algorithm). – Brilliand – 2014-06-24T21:05:43.990

1@Brilliand The argument passed to OrderBy isn't a static value, it's executed every time an element is sorted, and in this case returns random values without comparing any values. It would actually work correctly if the line was names = names.OrderBy(name => rng.Next()); – user3188175 – 2014-06-25T00:12:59.067

1The => indicates that this is a C# lambda expression (closure). – Snowbody – 2014-06-25T17:38:10.893

44

PowerShell

$names = @{0='John'; 1='Jeff'; 2='Emma'; 3='Steve'; 4='Julie'}
$id = random -maximum $names.Length
$names[$id]

This will always output John.

$names is a System.Collections.Hashtable which doesn't have a Length property. Starting with PowerShell v3, Length (and also Count) can be used as a property on any object. If an object does not have the property, it will return 1 when the object is not null, else it will return 0. So in my answer, $names.Length evaluates as 1, and random -maximum 1 always returns 0 since the maximum is exclusive.

Rynant

Posted 2014-06-16T12:17:01.047

Reputation: 2 353

42

Q

show rand `John`Jeff`Emma`Steve`Julie;
exit 0;

Q always initialises its random number seed with the same value.

skeevey

Posted 2014-06-16T12:17:01.047

Reputation: 4 139

8so basically it's not random at all – Sam Creamer – 2014-06-16T14:39:52.470

3@SamCreamer The purpose of the question is very much to make the output non-random. But this does look random so it definitely fits the bill – Cruncher – 2014-06-17T13:54:50.797

4Sorry, I meant Q's random numbers aren't that random, this question does certainly meet the criteria. Didn't mean to come across that way! – Sam Creamer – 2014-06-17T15:31:21.297

Yeah, so you have to find your own way to generate a random seed every time you want to use rand? Sounds... useful. – DLeh – 2014-06-19T16:20:34.253

1Can set the random seed manually very easily...start the interpreter with the -S 1234 option or do \S 1234 from the interpreter – skeevey – 2014-06-19T18:02:23.347

34

Perl

use strict;

my @people = qw/John Jeff Emma Steve Julie/;
my @index = int(rand() * 5);

print "Person @index is buying: $people[@index]\n";

Prints: Person X is buying: Jeff (where X is from 0-4)

Abusing scalar context a bit. @index = int(rand() * 5) places a random integer from 0 - 4 in the 0th position of the @index list. When printing the array, it properly prints the random integer in @index, but when using as an array index in $people[@index], @index uses scalar context, giving it the value of the list size, i.e. 1.

Interestingly enough, @people[@index] makes it index properly.

Interestingly enough @people[@index] is a hash slice in Perl, so @index is evaluated in the list context; in this case, it's a single entry list and that's why it works correctly

Allen G

Posted 2014-06-16T12:17:01.047

Reputation: 1 825

So in C(++) terms, there is an implicit conversion from list to scalar happening because when indexing, a scalar is expected? – iFreilicht – 2014-06-18T14:15:24.937

@iFreilicht Correct. In Perl, expressions can be evaluated as a list or as a scalar, depending on where they appear. As a result, the same expression might mean different things, depending on context. A list variable (i.e. a variable with the @ prefix), in "list context," is interpreted as all its elements, but in "scalar context," is a scalar equal to the total number of elements in the list. Hence, inside the string, the list variable has list context and gets interpolated, and we get Person X is buying. But as an array index, it gets scalar context, and gets interpreted as 1. – Allen G – 2014-06-18T15:29:55.210

3Problem with this is that when a Perl programmer sees my @index = ..., he immediately wonders "WTF?!". – derobert – 2014-06-19T19:16:58.173

@derobert, Why would you wonder? You see code like that quite often... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words; etc. – Matthias – 2014-06-26T14:44:47.323

@Matthias because the line is to pick and store a single value, and instead of a scalar it's being stored in an array. – derobert – 2014-06-26T15:02:01.810

@derobert, OK I give you that. Although I still do not feel unfamiliar with that line (and I am working with perl quite often). – Matthias – 2014-06-26T15:16:56.310

23

ECMAScript

// Randomly pick a person on only one line!
var people = [('John', 'Jeff', 'Emma', 'Steve', 'Julie')];

console.log(people[new Date() % people.length | 0]);

It always picks Julie.

It has brackets inside the square brackets, and the comma operator returns the value of its right operand.
It's also very easy to miss. I've missed it before in real code.

Toothbrush

Posted 2014-06-16T12:17:01.047

Reputation: 3 197

This is delightful. Finally, a use for that terrible, terrible operator. – Keen – 2014-06-17T16:31:09.703

5

The comma in that context is technically an operator, rather than a separator. http://www.ecma-international.org/ecma-262/5.1/#sec-11.14 And it is terrible. Unless you want your code to be hard to read. As you do here. So, kudos.

– Keen – 2014-06-17T20:18:41.690

2@Cory Yes, I agree - although I use it all the time for Code Golf with function expressions (e.g. (a,b)=>(a=b[0],b)). I've clarified my answer. – Toothbrush – 2014-06-17T22:28:27.863

21

C#

using System;

namespace LetsTroll {
    class Program {
        static void Main() {
            var names = new string[]{ "John", "Jeff", "Emma", "Steve", "Julie" };
            var random = new Random(5).NextDouble();
            var id = (int)Math.Floor(random);
            Console.WriteLine(names[id]);
        }
    }
}

The trick is, the method new Random().NextDouble() returns a double between 0 and 1. By applying Math.Floor() on this value, it will always be 0.

Knerd

Posted 2014-06-16T12:17:01.047

Reputation: 1 251

24It didn't withstand my quick glance. ;) – Martin Ender – 2014-06-16T12:42:26.023

@m.buettner damn you ^^ Lets see how it is about other members :P – Knerd – 2014-06-16T12:48:09.343

Would be more underhanded if there were something to suggest that the RNG knew you wanted a value up to 5. – Tim S. – 2014-06-16T14:11:39.797

1@TimS. like that? :P – Knerd – 2014-06-16T14:17:34.913

2+1, Much better - I know what you're really doing, but it could fool someone not too familiar with the API. – Tim S. – 2014-06-16T14:20:07.513

1I don't know about this. If you are going to specify a seed, why not just use the proper way of getting a "random" int: var random = new Random(5); var id = random.NextInt(5); – clcto – 2014-06-16T15:08:58.340

2@clcto In my opinion, including it twice is more likely to make someone do a double take, ask why, and see the problem. Including it once, and then including unnecessary code afterward, gives a bit of redirection/underhandedness. Bonus: if someone fixes one of the bugs, another exists. – Tim S. – 2014-06-16T15:30:02.637

18

C#

var names = new string[] {"John", "Jeff", "Emma", "Steve", "Julie"};
var guidBasedSeed = BitConverter.ToInt32(new Guid().ToByteArray(), 0);
var prng = new Random(guidBasedSeed);
var rn = (int)prng.Next(0, names.Length);
Console.WriteLine(names[rn]);

Hint:

Generate seed from GUID. Guids have 4 × 10−10 chance of collision. Super random.

Answer:

At least when you use Guid.NewGuid(), whoops! (Sneaky way to make seed always 0). Also pointless (int) for misdirection.

Nathan Cooper

Posted 2014-06-16T12:17:01.047

Reputation: 617

The other way I might do it, is to get AddRange muddled with Concat when adding names to a List<string>. Did occur to me to have a Hashset with a sneaky IEqualityComparer, but it would be just far too unusual. In my credit there weren't many (if any) seed based answers when I posted this. – Nathan Cooper – 2014-06-16T14:08:11.867

I'll guess you had the same idea as I did, but you were a bit faster and made it a bit harder to see. +1! – tsavinho – 2014-06-16T14:47:08.573

7Seeding the random number generator is an obvious trick, but you've hidden it brilliantly here. Lovely work. – TRiG – 2014-06-16T23:50:56.560

18

bash / coreutils

This is taken almost verbatim from a script I wrote for a similar purpose.

#!/bin/bash
# Sort names in random order and print the first
printf '%s\n' John Jeff Emma Steve Julie | sort -r | head -1

Even forgetting to use an upper case R is a mistake I have occasionally made in real life scripts.

kasperd

Posted 2014-06-16T12:17:01.047

Reputation: 829

3could you give a better explanation? Your current one is really short and not helpful to someone who isn't really familiar with bash. – iFreilicht – 2014-06-18T14:16:44.150

6-r specifies reverse (lexicographic) sort, so Steve will always be picked. It could be seen as an innocent typo of -R for random sort – Max – 2014-06-18T16:15:38.413

3That's a good reminder not to trust comments, but to carefully read the code! – TecBrat – 2014-06-20T17:34:26.223

16

Ruby

names = ["John", "Jeff", "Emma", "Steve", "Julie"]

puts names.sort{|x| rand()}.first

This would work correctly with sort_by, but sort expects a comparison function that works like <=>. rand()'s result will always be positive, so it will always produce equivalent results provided your Ruby implementation's sort algorithm is deterministic. My Ruby 1.9.3 always outputs Julie.

histocrat

Posted 2014-06-16T12:17:01.047

Reputation: 20 600

12

Ruby

names = ["John", "Jeff", "Emma", "Steve", "Julie"]

puts names[rand() % 5]

rand() with no arguments produces a random float between 0 and 1. So modulo 5 does nothing, and when slicing into an array with a float argument Ruby just rounds it down, so this always returns John.

histocrat

Posted 2014-06-16T12:17:01.047

Reputation: 20 600

11

Perl

three srands will make it three times more random!

#!perl
use feature 'say';

sub random_person {
    my ($aref_people) = @_;
    srand; srand; srand;
    return $aref_people->[$RANDOM % scalar @$aref_people];
}

my @people = qw/John Jeff Emma Steve Julie/;
my $person = random_person(\@people);

say "$person makes next round of drinks!";

explanation

there is no $RANDOM in perl, it's an undefined variable. the code will always return the first element from the list - drinks on John :)

edit:

after going through the code, one of the five guys has decided to fix the obvious error, producing the following program:

#!perl
use feature 'say';

sub random_person {
    my ($aref_people) = @_;
    return $aref_people->[rand $#$aref_people];
}

my @people = qw/John Jeff Emma Steve Julie/;
my $person = random_person(\@people);

say "$person buys next round of drinks!";

can you tell who did it just by looking at the code?

explanation:

in Perl, $#array returns the index of last element; since arrays are zero-based, given a reference to an array with five elements, $#$aref_people will be 4.
rand returns a random number greater or equal to zero and less than its parameter, so it will never return 4, which effectively means Julie will never buy drinks :)

chinese perl goth

Posted 2014-06-16T12:17:01.047

Reputation: 1 089

1$RANDOM is a real feature in bash, ksh and zsh (but not in perl). – kernigh – 2014-06-16T19:21:00.620

10

Python

Everybody knows that you can't trust randomness in such a small sample space; to make it truly random, I've abandoned the outdated method of picking a name from a list, and instead my program will spell out a completely random name. Since most of the names in the office had 4 letters, we'll settle for that.

import random

def CHR (n):
    # Just easily convert a number between 0 and 25 into a corresponding letter
    return chr(n+ord('A'))

# Seed the RNG with a large prime number. And multiply it by 2 for good measure.
random.seed (86117*2)

# Now, let's see what COMPLETELY RANDOM name will be spelled out!
totallyRandomName = ''
for i in range(4) :
    totallyRandomName += CHR(int(random.random()*26))

print (totallyRandomName)

Naturally, I did some preparation work to make sure I pick the right seed.

Tal

Posted 2014-06-16T12:17:01.047

Reputation: 1 358

15Seeding the random number generate with a constant is just too obvious.. – Brendan Long – 2014-06-16T22:59:05.830

@BrendanLong It would definitely raise eyebrows. People would want to test it to make sure its random. And when it's not, guess who's buying drinks. – JFA – 2014-06-25T17:39:43.387

10

C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
char *name[]={"John", "Jeff", "Emma", "Steeve", "Julie"};

int i;
int n=rand()%10000;
int r=3;

for (i=0; i<10000+n; i++) // random number of iteration
    {
    r=(r*r)%10000; // my own PRNG (square and mod)
    }

printf("%s", name[r%5] );
}

Sorry, Jeff!

After a few iteration r==1 mod 5, because of math. Morality : don't write your own PRNG if you're bad at math. :)

cpri

Posted 2014-06-16T12:17:01.047

Reputation: 727

10

C++x11

#include <vector>
#include <iostream>

int main () {
  std::srand(time(NULL));
  std::vector<std::string> choice{("jen","moss","roy")};
  std::cout << choice[rand()%choice.size()] << std::endl;
}

Size of vector is actually 1 due to the parenthesis used in the initializer list. Comma operator will discard all the names and return the last one, hence the buyer is always Roy.

tomasz

Posted 2014-06-16T12:17:01.047

Reputation: 281

10

Scala

I know my users will be skeptical, so I have included a proof that my randomness is truly fair!

object DrinkChooser {

  def main(args: Array[String]): Unit = {
    proveRandomness()
    val names = List("John","Jeff","Emma","Steve","Julie")
    val buyer = names(randomChoice(names.size))
    println(s"$buyer will buy the drinks this time!")
  }

  def proveRandomness(): Unit = {
    val trials = 10000
    val n = 4
    val choices = for (_ <- 1 to 10000) yield randomChoice(n)
    (choices groupBy(identity)).toList.sortBy(_._1) foreach { case (a, x) =>
      println(a + " chosen " + (x.size * 100.0 / trials) + "%")
    }
  }

  def randomChoice(n: Int): Int = {
    var x = 1
    for (i <- 1 to 1000) { // don't trust random, add in more randomness!
      x = (x * randomInt(1, n)) % (n + 1)
    }
    x
  }

  // random int between min and max inclusive
  def randomInt(min: Int, max: Int) = {
    new scala.util.Random().nextInt(max - min + 1) + min
  }

}

One example run:

1 chosen 25.31%
2 chosen 24.46%
3 chosen 24.83%
4 chosen 25.4%
John will buy the drinks this time!

Unless someone else gets extremely lucky, John will always buy the drinks.

The "proof" of randomness relies on the fact that rand(1, 4) * rand(1, 4) % 5 is still evenly distributed between 1 and 4, inclusive. But rand(1, 5) * rand(1, 5) % 6 is degenerate. There's the possibility you get a 0, which would then make the final result 0 regardless of the rest of the "randomness".

Joe K

Posted 2014-06-16T12:17:01.047

Reputation: 1 065

10

Javascript (with Underscore.js)

Since javascript does not have a built in shuffle we'll be using Underscore.js

var people = ['John', 'Jeff', 'Emma', 'Steve', 'Julie'];
_.shuffle(people); // Shuffle the people array
console.log("Next round is on", people[0]);

_.shuffle returns the shuffled array, it does not modify in place as Array.prototype.sort(), sorry John

Kristoffer Sall-Storgaard

Posted 2014-06-16T12:17:01.047

Reputation: 489

9

JavaScript

Second try, this one's a little trickier:

var getRandomEntry = function(args){
    return args[Math.floor(Math.random() * arguments.length)]; 
}

alert(getRandomEntry(["peter","julie","samantha","eddie","mark"]));

The arguments variable is locally accessible for functions and is an array of all arguments passed in to the function. By using simple naming and passing in an array to the function itself, you can spoof that we're not taking the length of the array, but in fact the length of the arguments list (which is 1). This can be even better executed by using special chars or a font type.

thomaux

Posted 2014-06-16T12:17:01.047

Reputation: 219

This wasn't the hardest to spot. Anyone who has constructed an arbitrary N-ary function in JavaScript knows about the arguments variable. – Conor O'Brien – 2015-10-23T04:00:44.807

8

C++

To be fair we should run many, many trials and pick whomever is selected the most often.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <map>

static const char *names[] = { "John", "Jeff", "Emma", "Steve", "Julie" };

int main() {
    srand(time(NULL));
    std::map<int, int> counts;

    // run 2^31 trials to ensure we eliminate any biases in rand()
    for (int i = 0; i < (1<<31); i++) {
        counts[rand() % (sizeof(names)/sizeof(*names))]++;
    }

    // pick the winner by whomever has the most random votes
    int winner = 0;
    for (std::map<int, int>::const_iterator iter = counts.begin(); iter != counts.end(); ++iter) {
        if (iter->second > counts[winner]) {
            winner = iter->first;
        }
    }

    printf("%s\n", names[winner % (sizeof(names)/sizeof(*names))]);
}

What's the value of 1<<31? Sorry, John.

fluffy

Posted 2014-06-16T12:17:01.047

Reputation: 725

The answer to your spoiler question is UB. I am undecided if that makes is better or worse. – nwp – 2014-06-22T17:57:52.593

@nwp Well, sure, but it holds anywhere that int is 32-bit 2's complement, which seems to be the case even on 64-bit (with gcc). I haven't tested on Clang, though. – fluffy – 2014-06-22T20:16:43.790

No it doesn't hold anywhere where an int is 32-but 2's complement. The value of 1 << 31 is undefined. You are lucky though, undefined behavior makes the compiler chose whatever it feels like and since it is made for speed it will just decide to do nothing, which happens to be what you want. – nwp – 2014-06-22T20:24:11.873

@nwp 1<<31 == 0x80000000 no matter what, by the very definition of <<, and on 32-bit 2's complement, that's INT_MIN. Are you maybe thinking about 1<<32 which may or may not == 0? (Because on x86, 1<<32 usually evaluates to 1...) – fluffy – 2014-06-23T18:18:46.403

@nwp It's actually implementation-defined. Now if we were talking about C, then it would be undefined. – Stuart Olsen – 2014-06-25T18:01:22.687

7

Lua

buyer={'John', 'Jeff', 'Emma', 'Steve', 'Julie'}
   -- use clock to set random seed
math.randomseed(os.clock())
   -- pick a random number between 1 and 5
i=math.random(5)
io.write("Today's buyer is ",buyer[i],".\n")

os.clock() is for timing purposes, os.time() is what ought to be used with math.randomseed for good RNG. Sadly, Julie always buys (at least on my computer).

Kyle Kanos

Posted 2014-06-16T12:17:01.047

Reputation: 4 270

math.random() with no arguments also returns a number in the range [0,1). -1 for not catching that. – mniip – 2014-06-16T17:04:31.613

@mniip: Truly deserved too! I've fixed it now. – Kyle Kanos – 2014-06-16T17:37:17.853

7

T-SQL (2008+)

SELECT TOP 1 name
FROM
 (VALUES('John'),('Jeff'),('Emma'),('Steve'),('Julie')) tbl(name)
ORDER BY RAND()

Explanation:

In MS SQL Server, RAND() only evaluates once per execution. Every name always gets assigned the same number, leaving the original ordering. John is first. Sucks for John.

Suggested improvement:

T-SQL can produce decent quality, per-row random numbers with RAND(CHECKSUM(NEWID())).

comfortablydrei

Posted 2014-06-16T12:17:01.047

Reputation: 701

I think ORDER BY NEWID() will suffice (no need to CHECKSUM) – Jacob – 2014-06-17T04:41:08.113

6

Idiomatic C++11

When drinks are involved, it's especially important to be up to date with the latest standards and coding styles; this is a great example of a highly efficient and idiom-compliant C++11 name picker.

It is seeded from the system clock, and outputs the seed along with the name for verification each time.

#include <vector>
#include <chrono>
#include <random>
#include <iostream>

auto main()->int {
  std::vector<std::string> names;           // storage for the names
  names.reserve(5);                         // always reserve ahead, for top performance
  names.emplace_back("John");               // emplace instead of push to avoid copies
  names.emplace_back("Jeff");
  names.emplace_back("Emma");
  names.emplace_back("Steve");
  names.emplace_back("Julie");

  std::mt19937_64 engine;                   // make sure we use a high quality RNG engine
  auto seed((engine, std::chrono::system_clock::now().time_since_epoch().count()));  // seed from clock
  std::uniform_int_distribution<unsigned> dist(0, names.size() - 1);     // distribute linearly
  auto number(dist(engine));                // pick a number corresponding to a name
  std::string name(names.at(number));       // look up the name by number
  std::cout << "Seed: " << seed << ", name: " << name << std::endl;  // output the name & seed
  return EXIT_SUCCESS;                      // don't forget to exit politely
}

Try this live: http://ideone.com/KOet5H

Ok so this actually is pretty good code overall; there are a lot of red herrings to make you look too closely at the code to notice the obvious - that the RNG is never actually seeded :) In this case seed is just an integer, and while it looks like engine is passed as a parameter to a seeding function, it's actually just ignored. The seed variable really is set from the clock, so it can be output at the end along with the name to add insult to injury, but it'll still always be Steve who buys the drinks.

Riot

Posted 2014-06-16T12:17:01.047

Reputation: 4 639

1It kills me that it doesn't use an initializer list for the names. At the very least, you've definitely succeeded in providing code that just feels over- engineered. I can't tell whether it's because of the "compliance" or all of the noise comments :P – vmrob – 2014-06-22T17:03:33.440

6

JavaScript

console.log(["Jeff", "Emma", "Steve", "Julie"][Math.floor(Math.random(5))]);

Well, sorry, Math.random doesn't take a parameter, and will always return a number from [0, 1). Still, it is a happy variadic function and doesn't complain about arguments!

Bergi

Posted 2014-06-16T12:17:01.047

Reputation: 967

5

Python

names=["John", "Jeff", "Emma", "Steve", "Julie"]
import random # Import random module
random.seed(str(random)) # Choose strictly random seed
print(random.choice(names)) # Print random choice

str(random) gives a constant string; not a random value

QuadrExAtt

Posted 2014-06-16T12:17:01.047

Reputation: 211

6A somewhat-irrelevant note: if you're using Python 3.2 or later, the second argument to random.seed() must be 2 (the default). If you pass version=1, the hash() of the string will be used as a seed instead of the entire string, and because Python randomly seeds strings' hash values starting in 3.2, you'll get an actually-random name. – Blacklight Shining – 2014-06-16T22:56:10.083

5

Perl

Emma had better not forget her purse! Runs under strict and warnings.

use strict;
use warnings;

# Use a hash to store names since they're more extendible

my %people;
$people{$_}++ for qw/John Jeff Emma Steve Julie/;

print +(@_=%people)[rand@_];  # 'cos (keys %people)[rand( keys %people )]
                              # is just too long-winded.

Explanation here.

Zaid

Posted 2014-06-16T12:17:01.047

Reputation: 1 015

Perl 5.18 changed this a bit, by introducing hash key randomization (to avoid hash collision complexity attacks). – Konrad Borowski – 2015-01-02T09:47:37.303

4

JavaScript

function getDrinksBuyer(){ 
    var people = ["Jeff", "Emma", "Steve", "Julie"];
    var rand = Math.random(0,4)|0;
    return people[rand];
}

The |0 results in 0 all the time but looks like it's doing some other rounding.

Matt

Posted 2014-06-16T12:17:01.047

Reputation: 777

I like it. Though I would do parseInt(Math.random(0, 4)) and maybe add comments like - Math.random returns a double, so convert it to an integer first – Claudiu – 2014-06-16T15:39:20.500

5The trick is actually that Math.random cares nothing for our meager parameters. It chooses numbers its own way. the |0 is correctly rounding the unexpected result, and so is not a source of any trickery. – Keen – 2014-06-17T16:35:41.863

|0 is very obvious to some (all of us most likely), but I would bet there's a lot who have no idea what it does. That's the group I was relying on tricking. – Matt – 2014-06-18T05:04:41.563

3@Matt I mean that |0, if you know what it does, looks like it's rounding down, and it is rounding down, so it's not a deception. (And if someone has no idea what |0 does, then there's no use for deceptive code; you can just tell them whatever you want them to believe.) Instead, the unexpected behavior in your answer is based on the fact that Math.random(0,4) is functionally identical to Math.random(), because Math.random doesn't use parameters. – Keen – 2014-06-19T19:18:20.583

4

J

;(?.5) { 'John'; 'Jeff'; 'Emma'; 'Steve'; 'Julie'

Poor Julie... Trivia: this might've been the cleanest J I've ever written...

This code is actually correct, except for one thing. ?. is the uniform rng: ?.5 will always return 4. ?5 would've been correct.

ɐɔıʇǝɥʇuʎs

Posted 2014-06-16T12:17:01.047

Reputation: 4 449

4

Java

Shh, don't tell anyone. Secretly call the second method in your code, then call the first method.

public String randomPerson() {
    String people[] = new String[]
    {"John", "Jeff", "Emma", "Steve", "Julie"};
    return people[Math.random()];
}

@SuppressWarnings("serial")
private void setUpRandomness() {
    try {
        Field field = Math.class.getDeclaredField("randomNumberGenerator"); 
        field.setAccessible(true);
        field.set(null, new Random() { 
            @Override
            public double nextDouble() {
                return 4; // chosen by fair dice roll.
            }             // guaranteed to be random.
        });               // Proof: http://xkcd.com/221/
    }
    catch (final SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException e)
    { /* Ignore */ }
}

Unihedron

Posted 2014-06-16T12:17:01.047

Reputation: 1 115

2Cudos on the xkcd reference :) – TMH – 2014-06-17T07:56:26.733

1This "random" number generator is not funny. Plus, Anubian Noob did this about 16 hours before you did. – Kyle Kanos – 2014-06-17T14:36:02.293

@KyleKanos I would argue that his script is not at all random while mine involves Math.random(), a Java standard method for getting a random double. – Unihedron – 2014-06-18T19:00:59.737

1I am by no means even a capable Java programmer, but it seems to me that you are overriding Java's standard method of getting a random double and replacing it with a very tired joke. – Kyle Kanos – 2014-06-18T19:12:40.200

4

Javascript

In order to make things as fair as possible, we'll simply outsource random-number generation to the random.org API. As you can see from this URL, the API can generate a random number between 0 and 4, inclusive, using extremely powerful entropy sources like atmospheric noise -- vastly superior to whatever your office laptop uses to generate /dev/random.

var xhr = new XMLHttpRequest();
xhr.open("GET",
    "http://www.random.org/integers/?num=1&min=0&max=4&col=1&base=10&format=plain&rnd=new");
xhr.send();

// convert string response to number
var index = +xhr.responseText;
var name = ["John", "Jeff", "Emma", "Steve", "Julie"][index];
alert(name);

There is a misuse of asynchronous Ajax code (a perennial Stack Overflow "favorite"). xhr.responseText is by default the empty string, and is not populated until the load event fires, so +"" is coerced to 0, leaving poor John to get drinks for everyone.

apsillers

Posted 2014-06-16T12:17:01.047

Reputation: 3 632

I had thought about doing exactly this, since it's a genuine common error for new programmers, and going to random.org is a perfect excuse. Might I suggest replacing +xhr.responseText with xhr.responseText|0 so that it looks even more like a reliable integer coercion? – Keen – 2014-06-24T19:57:05.880

3

AWK

BEGIN {
    srand(n=split("John Jeff Emma Steve Julie.",A))
    print A[int(rand()*n+1)]
}

Sorry, Steve!!! :-P

Feeding srand() with a constant shall reproduce the same sequence of rand() values over and over again. On my system gawk and mawk selected Steve but this may not be globally immutable...

But now for something completely different with really seeding srand():

BEGIN {
    srand()
    split("John Jeff Emma Steve Julie.",A)
    print A[int(rand()+1)]
}

Sorry, John!

srand() really seeds the rand() as expected and rand()+1 looks like correctly taking care of the names are stored in A[1] and following indices but because rand() always is smaller than 1, int(rand()+1) always will be 1.

user19214

Posted 2014-06-16T12:17:01.047

Reputation:

3

Kona

> buyer:("john";"jeff";"emma";"steve";"julie")
> *buyer[4 _draw 1]
"john"

x _draw y returns x number of values between 0 and y-1. To the untrained eye, this dyad appears to be pulling 1 value in the range 0 to 4, rather than 4 values in the range 0. Thus, buyer[4 _draw 1] is a vector with 4 elements that are all "john" (who sadly, again, is buying for everyone); the leading * picks the first element of the vector.

Kyle Kanos

Posted 2014-06-16T12:17:01.047

Reputation: 4 270

3

Bash

#!/bin/bash
output="";
until [ -n "$output" ];do
output=`echo John Jeff Emma Steve Julie|sed 's/ /\n/'|shuf|head -n1|sed '/[^a-zA-Z]/d;'`;
done
echo $output

Portability

This isn't entirely portable. It works on Ubuntu 14.04 with GNU bash 4.3.11, GNU coreutils 8.21 and GNU sed 4.2.2. In OpenBSD, according to @kernigh, the \n escape in the regex replacements doesn't work properly, and shuf doesn't exist.

Explanation

This makes extra checks to ensure that its output is valid. It initialises a variable to the empty string, then obtains random names for it with a loop. The loop loops until the variable is not empty. Unless the name chosen in any iteration is valid (only contains letters a-z and A-Z), the variable is set to the empty string, causing the loop to run again.

So, if the large command in the loop produces invalid output, it is discarded, until valid output is produced. It is then printed.

The central command echoes the five names separated by spaces to sed 's/ /\n/', which turns the spaces into newlines to be passed to shuf, which shuffles the lines in its input (only operates on lines, hence the sed command is needed, head -n1, which takes the first one, and sed '/[^a-zA-Z]/d;', which discards any invalid input it receives.

The first sed command doesn't have the g switch; only one substitution is made. Then, there are only two options: John and Jeff Emma Steve Julie. The latter is discarded later on. Sorry, John.

user16402

Posted 2014-06-16T12:17:01.047

Reputation:

1This one is not portable. Here with OpenBSD, sed 's/ /\n/' changes the first space to a literal n, because \n is only a newline in regular expressions, not in replacements. (I wonder if I can exploit this?) Also, there is no shuf command. So $output is always empty and this script enters an infinite loop, which is proof that the [ -n "$output" ] check is an essential part of the script. – kernigh – 2014-06-16T19:29:28.907

@kernigh Works fine on Ubuntu 14.04, GNU bash 4.3.11, GNU coreutils 8.21, GNU sed 4.2.2. shuf is in coreutils on my system. You could use sort -R instead of shuf, but it isn't quite the same (see manpages for details). – None – 2014-06-16T19:53:12.367

3

JavaScript

This answer is obvious but still, im giving a shot at it :

var arrName = ["Jeff", "Emma", "Steve", "Julie"];

randName.call.apply(getName, arrName)

function randName(){
    var names = Array.prototype.slice.call(arguments)

    this.call(names[Math.floor(Math.random() * names.length)]);
}

function getName(){
    alert(this)
}

Poor Jeff, he will always have to buy the drinks.

The trick here is in the call.apply(). The function being called is not the randName, but directly getName where this this will be equal to the first cell in the array.

Karl-André Gagnon

Posted 2014-06-16T12:17:01.047

Reputation: 141

Very odd code with a good idea :-) But randName on itself should be working, and use its arguments instead of the global arrName variable. – Bergi – 2014-06-20T08:26:52.050

@Bergi what a brain fart, even prepared that array! Thank anyway – Karl-André Gagnon – 2014-06-20T12:42:38.857

3

Java

In college, I was told that this would normally distributed.

public static void main(String[] args)
{
    String names = {"John", "Jeff", "Emma", "Steve", "Julie"};
    Random r = new Random();
    double res = Math.abs(r.nextGaussian()) * 0.5;
    int resInt = Math.min(names.length() - 1, (int) res);
    System.out.println(names[resInt]);
}

The nextGuassian() method picks a number from a pseudo normal distribution with mean 0 and standard deviation 1. So, basically the chances that it's not going to be John are 4.56%. Moreover, the chances it's going to be John or Jeff is approximately 100%.

Martijn Courteaux

Posted 2014-06-16T12:17:01.047

Reputation: 759

So will it always choose John OR Jeff not only one or did I misunderstand? – kitcar2000 – 2014-06-17T15:03:52.090

Yes, it's going to be John or Jeff, it will be 95.44% of the time John and 4.56% of the time is it going to be Jeff. – Martijn Courteaux – 2014-06-17T15:21:40.623

Why are you taking the minimum? This looks suspicious. – Bergi – 2014-06-20T08:20:53.327

Because mathematically, a Gaussian random number kan be anything, even 1000000. So that's not what we want. – Martijn Courteaux – 2014-06-25T22:42:55.483

I agree that it looks too suspicious. It can be anything, but you can't let people know that, and it will practically never by more than 4. If your code fails once every 20,000 runs, that's fine. So if you remove the min you should be okay. – raptortech97 – 2014-08-08T19:44:57.063

3

C++

The idea is pretty simple: we generate n random numbers for each person (their score), add them together to get their total, and the person with the lowest total score has to buy the drinks. To be scrupulously fair, we generate the random numbers in n rounds, with each person taking turns to be the first to roll the dice.

#include <random>
#include <algorithm>
#include <iostream>

int main() {
    const char* names[] = {"John", "Jeff", "Emma", "Steve", "Julie"};
    constexpr unsigned int NumNames = std::extent<decltype(names)>::value;
    unsigned int total[NumNames] = {};

    std::random_device rd;  // Seed with a real random value
    std::default_random_engine e1(rd());
    for (unsigned int i = 0; i != NumNames; ++i) {
        unsigned int score[NumNames];
        std::generate(std::begin(score), std::end(score), e1);
        for (unsigned int j = 0; j != NumNames; ++j)
            total[(i + j) % NumNames] += score[j];  // Eliminate any bias
    }

    auto loser = names[std::distance(std::begin(total),
            std::min_element(std::begin(total), std::end(total)))];
    std::cout << loser << " buys the drinks!\n";
}

Explanation:

Unfortunately, std::generate takes its functor argument by value, not by reference, so modification to the internal state of the engine only affects the copy of e1 inside std::generate. That means that each time round the loop score is filled with the same sequence of values, so after the loop everyone has exactly the same total. When faced with a tie, std::min_element returns the first element with the minimum value, so John always buys the drinks!

This has resulted in real-world bugs: https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/nsGPpmEVOns/overview

ecatmur

Posted 2014-06-16T12:17:01.047

Reputation: 1 675

3

JavaScript

Two different flavors here.

var totallyFairAndRandomPersonPicker = function () {
    var people = ['John','Jeff','Emma','Steve','Julie'];
    var drawnLot = [0, 1, 2, 3, 4][Math.random()*people .length]|0;
    return people[drawnLot];
};

totallyFairAndRandomPersonPicker ();

I think I accidentally put a ] in the wrong place! Sorry, John!

var chooseOne = function (list) {
    // We use double the random calls for double the randomness!
    var  i = Math.random()*Math.random()*list.length|0;
    return list[i];
};

chooseOne(['John','Jeff','Emma','Steve','Julie']);

It's the answer you need, not the answer you want. Everybody has a chance of being selected, but it's still massively unfair to John. I apologize for any dismay it causes Julie to occasionally chip in.

Keen

Posted 2014-06-16T12:17:01.047

Reputation: 261

2

Python

from random import random
names = ['John', 'Jeff', 'Emma', 'Steve', 'Julie']
index = int(random()) * len(names) # Get a random number in range 0-4 (length of the list)
print names[index]

random.random() actually gives a value between 0.0-1.0, excluding 1.

seequ

Posted 2014-06-16T12:17:01.047

Reputation: 1 714

2

C#

Okay, one more.

I don't want to make anyone think there's any trickery here with regard to how random my random numbers are.

So I've got to great efforts to avoid passing anything to Random() or Random.Next(). It's a bit slow, but worth it for the extra integrity.

public class RandomDrinks
{
    int buyerIndex;
    string[] names = new string[] { "John", "Jeff", "Emma", "Steve", "Julie" };
    Random random = new Random();

    public string PrintBuyer()
    {
        //Get Random until there is a valid index
        do
        {
            buyerIndex = GiveMeRandoms();
        } while (!IsValueIsInRange(out buyerIndex));

        var text = names[buyerIndex];
        return String.Format("{0} is buying", text);
    }

    public int GiveMeRandoms()
    {
        return random.Next();
    }

    bool IsValueIsInRange(out int index)
    {
        int chosen = buyerIndex; 
        index = names.Length - 1;
        return !(chosen > index);
    }

}

is the effect of the out too obvious?

Nathan Cooper

Posted 2014-06-16T12:17:01.047

Reputation: 617

2

Ruby

names = ['John', 'Jeff', 'Emma', 'Steve', 'Julie']
puts names[Time.new.sec % names.length]

It's not random if you run it at a right moment... ;)

Tr00rle

Posted 2014-06-16T12:17:01.047

Reputation: 311

1So basically it's not random if you run it in exactly 5 second intervals? – seequ – 2014-06-16T17:05:45.187

1Sure, for example, if you need to get Jeff all the time, just run it at any of these seconds: 1, 6, 11, 16... – Tr00rle – 2014-06-16T17:23:51.690

2

JavaScript

function pick(names) {
  var r = Math.floor(Math.random * names.length);
  for (var i = 0; i < names.length; i++) { if (i >= r) { break; } }
  return names[i-1];
}
alert(pick(["John", "Jeff", "Emma", "Steve", "Julie"]));

The gods have spoken, Julie. Don't fight destiny.

Like all fearlessly awesome languages, JavaScript not only forgoes an exception and returns a value when you "invoke" a function without parenthesis; but also when you multiply by something that is not a number.

svidgen

Posted 2014-06-16T12:17:01.047

Reputation: 311

1This is fun, but a lot of languages fall sin to this, as Math.random returns the function itself, and it actually does let you know that the result of the multiplication doesn't make sense by returning NaN. The for loop looks suspect, so maybe you should consider doing this var ix =(Math.random * names.length)|0; This is pretty well known paradigm in javascript to turn a double into a number, and also turns your NaN into zero :) – Michael B – 2014-06-17T17:47:09.413

2

Atari BASIC

It generates a random number R, and then READs the appropriate number of names from the DATA statement until it reaches the buyer.

10 DIM NAME$(10)
20 R=RND(5)
30 FOR I=0 TO R
40 READ NAME$
50 NEXT I
60 PRINT NAME$
70 END
99 DATA John,Jeff,Emma,Steve,Julie

RND(x) always returns a floating-point number between 0 and 1; the parameter is ignored (but required because the BASIC parser can't deal with zero-arg functions). So, the loop always executes exactly once, and John is the buyer. The correct way to generate a random number between 0 and 4 is R=INT(5*RND(0)).

dan04

Posted 2014-06-16T12:17:01.047

Reputation: 6 319

2

C++

#include <string>
#include <algorithm>
#include <iostream>

int main(){
    using namespace std;
    const char *names[] = { "John", "Jeff", "Emma", "Steve", "Julie"};
    random_shuffle(begin(names), end(names));
    cout << names[0] << '\n';
}

This one fools even me. Why does it print out Julie every time?

nwp

Posted 2014-06-16T12:17:01.047

Reputation: 241

missing srand, glorious c++ ;) – tomasz – 2014-06-25T10:27:38.007

1

Sinclair BASIC

 10 LET r=INT RND*8
 20 LET n$=""
 30 IF r=0 THEN LET n$="John"
 40 IF r=1 THEN LET n$="Jeff"
 50 IF r=2 THEN LET n$="Jmma"
 60 IF r=3 THEN LET n$="Steve"
 70 IF r=4 THEN LET n$="Julie"
 80 PRINT "The person buying the drinks today is..."
 90 FOR d=0 TO 16 : REM Drum roll...
100 OUT 254,31
110 PAUSE 6-(d/4)
120 OUT 245,15
130 PAUSE 6-(d/4)
140 NEXT d
150 PRINT n$;"!"

Explanation:

The INT function only evaluates the item immediately after it so it performs (INT RND)*8 rather than INT (RND*8) so John will always buy the drinks.

kitcar2000

Posted 2014-06-16T12:17:01.047

Reputation: 2 689

"IF r=0 THEN" for all names is what you really intended? It looks like the last "IF" will set the name... so Julie will have to pay... – None – 2014-06-16T19:57:59.403

1

F#

This solution is very flexible -- it allows you to pick people in batches, so you won't have to run it again for a little while. Supply the number as the first argument to the program:

[<EntryPoint>]
let main argv =
  let getRandom (min, max) = (new System.Random()).Next (min, max)
  let pickBuyers people times = List.init times (fun _ -> List.nth people (getRandom (0, List.length people)))
  printfn "%A" (pickBuyers ["John"; "Jeff"; "Emma"; "Steve"; "Julie"] <| System.Int32.Parse argv.[0])
  0

! Exploits a common mistake when learning random numbers, so you probably caught this if you know the basics of System.Random. Instantiating Random() uses the time as a seed, and calling it in quick succession will cause it to seed exactly the same over and over until the time changes.

However (as pointed out by @kernigh), the more elements you generate at once, the more likely it is to roll over to the next millisecond before it's finished. This will cause the next RNGs to get seeded with a different number, thus changing the resulting number. This will happen every millisecond(?).

Jwosty

Posted 2014-06-16T12:17:01.047

Reputation: 3 530

The output looks suspicious: http://ideone.com/AHZVz5

– kernigh – 2014-06-25T22:04:03.243

I'm aware of that -- the more items you generate at once, the more likely it will be that it rolls over the millisecond, thus seeding the RNG differently. It's in the nature of this method, unfortunately. – Jwosty – 2014-06-25T22:53:28.900

1

C#

using System;
using ExtensionMethods;

namespace RandomBeerDrinker
{
    class Program
    {
        static void Main()
        {
            var generator = new Random();
            int person = generator.NextValue();
            var names = new[] {"John", "Jeff", "Emma", "Steve", "Julie"};
            Console.WriteLine(names[person]);
            Console.ReadLine();
        }
    }
}

Everyone's using extension methods nowadays, so it's not suspicious to have a class called ExtensionMethods, is it?

using System;
 namespace ExtensionMethods
    {
        public static class ExtensionMethods
        {
            public static int NextValue(this Random x)
            {
                return x.Next()%4; // Quite random, but excludes Julie
            }
        }
    }
 

Thomas Weller

Posted 2014-06-16T12:17:01.047

Reputation: 1 925

1

In order to be reusable, it is best to use generic functions with single purposes only, to assemble the complete program.

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <string>

// generic function to randomize elements of any passed container
template<class C>
void randomize_container( C elements )
{
    std::random_shuffle(elements.begin(), elements.end() );
}

std::string pick_one( std::vector<std::string> names )
{
    randomize_container( names );
    return names[0];
}

int main(int argc, const char *argv[])
{
    // Do not forget to seed the rng, but only once!
    srand(time(nullptr));

    auto ret = pick_one( { "John", "Jeff", "Emma", "Steve", "Julie" } );
    std::cout << ret << " has to pay the next round\n";
}

It should just simply have been C& instead of C to pass the container per reference.

PlasmaHH

Posted 2014-06-16T12:17:01.047

Reputation: 1 084

Saw this one immediately, but still laughed because it would be easy to miss, especially if your coworkers aren't familiar with C or C++. – Brendan Long – 2014-06-17T18:03:16.087

@BrendanLong: It is such a common mistake as you can see from the numerous questions on SO, that could be real world code ;) – PlasmaHH – 2014-06-17T19:33:10.897

1

Fortran 95

character(LEN=5), dimension(5) :: name=(/"John ","Jeff ","Emma ","Steve","Julie"/)
real :: ReallyReallyReallyRandomNumber = 0.

call RANDOM_NUMBER(ReallyReallyReallyRamdomNumber)

do i=1,5
    if (myReallyReallyRandomNumber <= real(i)/5.) then
        write(*,"(A,A)") "Selected name is: ", name(i)
        exit
    endif
enddo

end

I am assuming that your compiler generates a random seed which is different for every run. If not (which is the case of gfortran on my Windows machine), then you may like to add some code that generates a random seed before every run by using, for instance, the system's clock (see this link)

The variable that receives the random value is named ReallyReallyReallyRamdomNumber while the variable that is used in the loop is named ReallyReallyReallyRandomNumber (note that the first one is misspelled). This last variable is given an "initial" value of 0., which never changes, thus being the same regardless of the RANDOM_NUMBER subroutine. So, unfortunately for John, he will be selected every single time on every single machine.

gilbertohasnofb

Posted 2014-06-16T12:17:01.047

Reputation: 494

2Obviously doing the safe thing of opening with implicit none would defeat this. I think this might be the first code to abuse variable names rather than the RNG seed. +1 – Kyle Kanos – 2014-06-18T02:18:49.283

1@KyleKanos Thanks! Indeed this sort of code shows one more reason why implciit none should ALWAYS be present on a Fortran program. – gilbertohasnofb – 2014-06-18T10:04:53.727

1

C

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char *names[] = {"John", "Jeff", "Emma", "Steve", "Julie"};
    printf("%s\n", names[random() % 5]);
    return 0;
}

Always outputs Steve on my computer. (It might vary by computer, but will likely be consistent on one machine.)

This works because random() is usually a pseudo-random number generator; you must seed it with some randomness, or it will always give the same numbers in the same order.

BenjiWiebe

Posted 2014-06-16T12:17:01.047

Reputation: 231

1

Python

#!/usr/bin/env python3

import random

# Create list of names.
names = ['John', 'Jeff', 'Emma', 'Steve', 'Julie']

# Define start and end of range, just in case we want to change it in the future.
start = names.index(names[-1]) - len(names)
end = len(names)

# Randomly choose name from list, using range specified above.
print(random.choice(names[start:end]))

names[start:end] should be the same as names, but allows us to easily change the range in the future. However, instead of starting at 0, as we should, we sneakily start at -1. So, we actually pass names[-1:5] to random.choice, rather than names[0:5]. Thus, we always choose the last name in the list.

daviewales

Posted 2014-06-16T12:17:01.047

Reputation: 271

1

JAVA

public class RandomBuyer{
    static String[] names = {"John", "Jeff", "Emma", "Steeve", "Julie"};

    public static void main(String[] args){
        String buyer = names[0]; //Initialize buyer 
        setRandomBuyer(buyer);   //Set buyer to random
        System.out.println(buyer);
    }
    static void setRandomBuyer(String buyer){
        int random = new java.util.Random().nextInt(5);
        buyer = names[random];
    }
}

Explanation

Why this doesn't work!

Narmer

Posted 2014-06-16T12:17:01.047

Reputation: 149

1

Perl

While playing code golf, I tested this simple shuffle algorithm. It always picks Steve.

use strict;
use warnings;

# Randomness test for 0.5 - rand:
# perl -e 'for(1..10000){$x=0.5 - rand;$x<0&&$n++;$x>0&&$p++}' \
#      -e 'print "negative: $n, positive: $p\n"'

# Shuffle from alphabetical order to random order.
my @shuffled = sort { 0.5 - rand } qw(Emma Jeff John Julie Steve);
print "$shuffled[-1]\n";

Perl expects the sort block to return an integer, not a float. My block { 0.5 - rand } returns a random float from -0.5 exclusive to 0.5 inclusive, but Perl truncates this float toward 0 before checking its sign. Every float from -0.5 to 0.5 becomes integer 0, so all names compare equal and stay in alphabetical order.

If we fix the bug, this program would perform a "Microsoft shuffle", which is not a fair shuffle. Microsoft used 0.5 - Math.random() in JavaScript for a comparison function. That shuffle had much bias, because 0.5 - Math.random() does not provide a consistent ordering.

Find more Perl answers by Zaid, chinese perl goth, Allen G.

kernigh

Posted 2014-06-16T12:17:01.047

Reputation: 2 615

1

TI-BASIC

No computer handy? This works on all TI-83/84/+/SE calculators.

PROGRAM:RANDOM
:"NEW ARRAY NAME:"
:"JOHN"
:"JEFF"
:"EMMA"
:"STEVE"
:"JULIE"
:Disp "NAMES[floor(rand*5)]"
:Disp "NAME: ",Ans

The names are successively set into Ans (so JULIE would be the contents of Ans). Then, the NAMES[floor(rand*5)] is piped away as a useless string, and the last line looks line it is pulling one of the names from the array NAME (which doesn't exist, by the way). Instead, it will always display JULIE. The order of the names can be switched around to provide a different victim on demand.

Timtech

Posted 2014-06-16T12:17:01.047

Reputation: 12 038

0

C#

private void randomizer()
    {
        string[] allName = {"John", "Jeff", "Emma", "Steve", "Julie"};
        Random getRandomNumber = new Random(0);
        Console.WriteLine(allName[getRandomNumber.Next(0,4)]);
    }

Since I'm making a random with the seed of zero, the result will always be the same, in this special case it would be Emma.

tsavinho

Posted 2014-06-16T12:17:01.047

Reputation: 163

0

C++

#include<iostream>
#include<climits>
#include<cstdlib>
#include<cmath>

using namespace std;

const string names[]={ "John", "Jeff", "Emma", "Steve", "Julie" };

int main(){
    srand(time(NULL));
    // Generate a random real number
    double r=(double)rand()/(RAND_MAX+1.);

    // Convert it back into an integer
    unsigned long long x=round(r * (ULLONG_MAX+1.));

    // Simply use the remainder is a bit waste. Add up the digits in base 5 instead
    while(x >= 5)
        x=x/5 + x%5;

    // Print the answer
    cout<<names[x]<<endl;
    return 0;
}

Assume RAND_MAX is 2147483647. This program almost always prints Julie, with chances to print John when r is generated exactly zero.
Firstly, the real things you get in x is r*2^33. Then the while loop in fact computes something like x mod 4. And 4 is a divisor of 2^33. It is not the correct way adding up all digits, either.

jimmy23013

Posted 2014-06-16T12:17:01.047

Reputation: 34 042

0

Ozone

(s1v1(1)n1n1s2v21v21s3v3(<+2n2v12+1n1v21v03>)v03)

The trick is in "+2n2".

user25246

Posted 2014-06-16T12:17:01.047

Reputation: 19

This appears to be written in a language which doesn't support the generation of random numbers. How is it supposed to fool anyone? – Peter Taylor – 2014-06-17T11:44:27.320

4Maybe you could explain what the code actually did? – kitcar2000 – 2014-06-17T15:07:55.337

0

Java

import java.security.SecureRandom;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
public class ExampleCode
{
    public static void main( String A[] )
    {
        String[] P = "John Jeff Emma Steve Julie".split( " " );
        P = new HashSet<String>(Arrays.asList( P )).toArray(P);//this should change order of names to random
        Random R = new SecureRandom();//let's use good random number generator
        int O = R.nextInt( P.length );//select random number O
        System.out.println(P[0]);//Show the results
    }
}

Explanation

The line that changes order to "random" changes oreder, but not randomly. Variable with random number is called 'O' (uppercase 'o'), but when getting value from array '0' (result of 1-1) is used, which looks simillar to uppercase 'o'.

barteks2x

Posted 2014-06-16T12:17:01.047

Reputation: 281

http://meta.codegolf.stackexchange.com/a/1657/20356 – seequ – 2014-06-18T08:59:43.230

0

Simple solution using JavaScript

var randArrElement = function(arr){
   return arr[Math.ceil(Math.random()*(arr.length-1))];
   //arr[arr.length] is undefined because arrays are 0 indexed, so we subtract 1.
}
randArrElement(["John", "Jeff", "Emma", "Steve", "Julie"]);

First 10 results:
Steve, Steve, Jeff, Steve, Julie, Jeff, Emma, Emma, Steve, Julie

Expanation:

Because I round using ciel, the only way that John could get chosen is if Math.random()*(arr.length-1) is exactly equal to 0. Even if it is 0.0000001, ceil will round up to 1. So John never gets chosen.

potato

Posted 2014-06-16T12:17:01.047

Reputation: 111

You know, Math.random can return exactly 0. – pppery – 2015-11-02T18:45:30.713

@ppperry but it almost surely don't.

– Akangka – 2015-11-03T09:52:31.523

This is the wrong way around. You always exclude one instead of always picking that person. But I like the variant enough not to downvote :P – Martijn – 2014-06-26T14:35:39.603

0

PHP with microtime for extra randomisation

$names = array('John', 'Jeff', 'Emma', 'Steve', 'Julie');
$choosenPerson = false;
while($choosenPerson === false){
    // Use microtime for a very random value:
    $uid= substr(microtime(true), 0, 1);
    if( isset($names[$uid]) ){ $choosenPerson = $names[$uid]; }
}

Im going for the microtime misconception. Microtime suggests that we have a very random factor, but im taking the first character which is 1. So for the upcomming years, Jeff will loose a lot of money. After that it'll be Emma :)

Martijn

Posted 2014-06-16T12:17:01.047

Reputation: 713

0

Python 2

import random
names = ["John, Jeff, Emma, Steve, Julie"]
print random.choice(names)[:3]

Surprised nobody did something like this before.

"John, Jeff, Emma, Steve, Julie" is one string. Super obvious but whatevs

TheInitializer

Posted 2014-06-16T12:17:01.047

Reputation: 829

This doesn't print John, it prints Joh – pppery – 2015-11-02T14:04:24.013

0

Python

def iterate(names):
    for name in names:
        yield lambda:name
import random
print random.choice(list(iterate("John Jeff Emma Steve Julie".split())))()

Sorry, Julie!

The name variable int the iterate function is the same one as in the lambdas, so every lambda evaluates the the last name, Julie.

pppery

Posted 2014-06-16T12:17:01.047

Reputation: 3 987

-1

BASH / Coreutils

Quite a beginner at CG, but worth a shot:

RANDOM=$$;
a=$RANDOM
b=9
c=`expr $a % $b `
echo $c

$$ is the PID of the running shell, so the number should be always the same

german_guy

Posted 2014-06-16T12:17:01.047

Reputation: 569

What happens when you restart the shell? – Knerd – 2014-06-16T12:57:51.420

3Another number is printed, but always the same for that session – german_guy – 2014-06-16T12:59:20.860

1This does not work because I saved these commands in a script, and bash pick-someone-b.bash uses a different PID each time. – kernigh – 2014-06-16T19:34:13.413

Sorry... while doing the &&->$$$$ change the preview of the hidden text fooled me and showed only 2 $s... now there are 4 of then... can you check what happens in your browser with the preview of $$ while editing? If it is not a local browser problem, maybe StackExchange should get a hint about this... (Plus Megawink vom Niederrhein!) – None – 2014-06-17T22:12:37.887

Maybe it went wrong because I did it on the phone. Now it seems to work. Grüße an den Niederrhein ;) – german_guy – 2014-06-18T07:00:13.450

-3

JavaScript:

function ActuallyNotRandom() {
    this.names = ["John", "Jeff", "Emma", "Steve", "Julie"];

    this.choose = function()
    {
        return this.names[Math.random(this.names.length) * 0];
    }

    return this.choose();
}

console.log("Random person: " + ActuallyNotRandom());

Pretty straightforward, takes a list of names, makes a random number between 0 and the number of names in the list, and then multiplies it by 0 to always return 0. Will therefore actually always return the first name in the list and display it to console.

Derek

Posted 2014-06-16T12:17:01.047

Reputation: 103

4The *0 is very obvious. I suggest Math.floor(Math.random()) to hide it just a bit better – Martijn – 2014-06-17T12:09:04.393

Not that it matters after multiplying by 0, but Math.random(n) doesn't return return what you think it does. – Dennis – 2014-10-03T02:00:39.640