Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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

share|improve this question
40  
xkcd.com/221 –  AstroCB Jun 16 at 19:30
4  
@AstroCB one of my favourites. Right behind bobby tables. –  Cruncher Jun 16 at 20:08
45  
It seems like it would be sneakier if it was random, except for never picking one person. –  Brendan Long Jun 16 at 22:52
5  
@AstroCB this one is also fantastic: dilbert.com/strips/comic/2001-10-25 –  gilberto.agostinho.f Jun 18 at 10:08
2  
@AstroCB apparently, some large company cough - sony - cough did something similar –  iFreilicht Jun 18 at 14:00

63 Answers 63

up vote 155 down vote accepted

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.

share|improve this answer
12  
+1 for performance -- much faster than rolling a physical die! ;) –  Jwosty Jun 17 at 3:46
11  
I'm thinking about optimising it further, perhaps with SIMD or GPGPU, just to get a little more performance. ;-) –  Paul R Jun 17 at 7:12
4  
Absolutely real live applicable. No one would ever even question that it was an accident in the slightest. –  iFreilicht Jun 18 at 14:04
1  
@PaulR Congratulations, you're the highest voted answer after a week :). –  Tom Hart Jun 23 at 12:04
2  
@AlvinWong I didn't notice it immediately. Then again, I don't use C regularily, or any other language that descended from BCPL. –  Rhymoid Jun 23 at 12:52

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.

share|improve this answer
19  
You 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 Jun 16 at 16:18
116  
+1000 for "...alerting the programmer to a potential error is considered a deadly sin in PHP." –  jsedano Jun 16 at 16:51

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

share|improve this answer
19  
That's diabolical! –  Daenyth Jun 16 at 17:59
6  
Feels like photographing a dice which has not yet stopped moving. –  Vi. Jun 19 at 8:25
1  
@Vi. That is a nice analogy. Luckily the use of MVars guarantee that the picture will not be blurry. :) –  monocell Jun 19 at 8:41

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

share|improve this answer
6  
\o/ Mean!!! Really mean!!! $SECONDS ftw! \o/ –  yeti Jun 17 at 17:47
    
What happens if you source this, instead of just executing it? Will the shebang still trigger a new shell or something? –  jpmc26 Jun 26 at 14:22
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 Jun 26 at 21: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.

share|improve this answer
2  
+1 This one is nice :) –  Knerd Jun 16 at 12:49
1  
Even 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 Jun 24 at 21:05
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 Jun 25 at 0:12
    
The => indicates that this is a C# lambda expression (closure). –  Snowbody Jun 25 at 17:38

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.

share|improve this answer
2  
+1 - This is fantastic! –  Mitch Connor Jun 16 at 18:28

Q

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

Q always initialises it's random number seed with the same value.

share|improve this answer
4  
so basically it's not random at all –  Sam Creamer Jun 16 at 14:39
4  
but i still love it for some reason –  Sam Creamer Jun 16 at 14:40
2  
@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 Jun 17 at 13:54
3  
Sorry, 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 Jun 17 at 15:31
1  
Can set the random seed manually very easily...start the interpreter with the -S 1234 option or do \S 1234 from the interpreter –  slackwear Jun 19 at 18:02

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

share|improve this answer
2  
+1 that's the eviliest thing I ever saw :') –  Anzeo Jun 18 at 11:24
    
So in C(++) terms, there is an implicit conversion from list to scalar happening because when indexing, a scalar is expected? –  iFreilicht Jun 18 at 14:15
    
@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 Jun 18 at 15:29
1  
Problem with this is that when a Perl programmer sees my @index = ..., he immediately wonders "WTF?!". –  derobert Jun 19 at 19:16
    
@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 Jun 26 at 14:44

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.

share|improve this answer
21  
It didn't withstand my quick glance. ;) –  Martin Büttner Jun 16 at 12:42
1  
@TimS. like that? :P –  Knerd Jun 16 at 14:17
2  
+1, Much better - I know what you're really doing, but it could fool someone not too familiar with the API. –  Tim S. Jun 16 at 14:20
1  
I 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 Jun 16 at 15:08
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. Jun 16 at 15:30

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.

share|improve this answer
    
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 Jun 16 at 14:08
    
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 Jun 16 at 14:47
6  
Seeding the random number generator is an obvious trick, but you've hidden it brilliantly here. Lovely work. –  TRiG Jun 16 at 23:50

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.

share|improve this answer
3  
could you give a better explanation? Your current one is really short and not helpful to someone who isn't really familiar with bash. –  iFreilicht Jun 18 at 14:16
5  
-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 Jun 18 at 16:15
3  
That's a good reminder not to trust comments, but to carefully read the code! –  TecBrat Jun 20 at 17:34

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.

share|improve this answer
    
This is delightful. Finally, a use for that terrible, terrible operator. –  Cory Jun 17 at 16:31
    
@Cory Which operator are you referring to? –  toothbrush Jun 17 at 20:14
3  
The comma in that context is technically an operator, rather than a separator. 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. –  Cory Jun 17 at 20:18
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 Jun 17 at 22:28

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.

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer
13  
Seeding the random number generate with a constant is just too obvious.. –  Brendan Long Jun 16 at 22:59
    
@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 Jun 25 at 17:39

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

share|improve this answer
1  
$RANDOM is a real feature in bash, ksh and zsh (but not in perl). –  kernigh Jun 16 at 19:21

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

share|improve this answer

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.

share|improve this answer
    
The answer to your spoiler question is UB. I am undecided if that makes is better or worse. –  nwp Jun 22 at 17:57
    
@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 Jun 22 at 20:16
    
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 Jun 22 at 20:24
    
@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 Jun 23 at 18:18
    
@nwp It's actually implementation-defined. Now if we were talking about C, then it would be undefined. –  Stuart Olsen Jun 25 at 18:01

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.

share|improve this answer

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

share|improve this answer

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.

share|improve this answer

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

share|improve this answer

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

share|improve this answer
    
math.random() with no arguments also returns a number in the range [0,1). -1 for not catching that. –  mniip Jun 16 at 17:04
    
@mniip: Truly deserved too! I've fixed it now. –  Kyle Kanos Jun 16 at 17:37

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

share|improve this answer
    
I think ORDER BY NEWID() will suffice (no need to CHECKSUM) –  Jacob Jun 17 at 4:41

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

share|improve this answer
5  
A 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 Jun 16 at 22:56

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.

share|improve this answer

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.

share|improve this answer
1  
It 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 Jun 22 at 17:03

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.

share|improve this answer
    
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 Jun 16 at 15:39
5  
The 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. –  Cory Jun 17 at 16:35
    
|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 Jun 18 at 5:04
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. –  Cory Jun 19 at 19:18

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.

share|improve this answer

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!

share|improve this answer

protected by Doorknob Jun 17 at 14:01

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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