Script aleatório que não é realmente aleatório


106

Como uma pequena piada no escritório, alguém queria um roteiro que escolhesse um nome aleatoriamente, e essa pessoa fará uma rodada de bebidas.

Vamos chamar as pessoas de John, Jeff, Emma, ​​Steve e Julie.

Eu pensei que seria engraçado fazer um script que parecesse aleatório rapidamente, mas na verdade sempre dá a mesma pessoa que a saída (depende de você escolher).

A resposta mais votada vence depois de uma semana

E o vencedor é....

Paul R com (atualmente) 158 votos.

As respostas aqui são ótimas e, se alguém tiver outras idéias que ainda não foram publicadas, adicione-as, adoro ler.



6
@AstroCB um dos meus favoritos. Logo atrás de mesas de bobby.
— Cruncher

50
Parece que seria mais furtivo se fosse aleatório, exceto por nunca escolher uma pessoa.
— Brendan Longo

6
@AstroCB este também é fantástico: dilbert.com/strips/comic/2001-10-25
— gilbertohasnofb

3
Passei pela primeira página: a maioria das respostas sempre escolhe John, a segunda mais alta é Julie, Jeff é escolhido raramente e Steve por 1. Até Ray foi escolhido por um, mas ninguém escolheu Emma. Moral da história: quando estiver em uma fila para decidir aleatoriamente quem comprará as bebidas, nomeie-se Emma.
— Variável miserável

Respostas:


171

C

É importante decidir quem está comprando o mais rápido possível, para não perder um tempo precioso de bebida - portanto, C é a escolha óbvia para obter o máximo desempenho:

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

Explicação:

Isso funcionaria muito bem se houvesse um break;após cada caso na instrução switch. No entanto, como cada caso "passa" para o próximo, a pobre Julie sempre acaba comprando as bebidas.


17
+1 por desempenho - muito mais rápido do que rolar um dado físico! ;)
— Jwosty

16
Estou pensando em otimizá-lo ainda mais, talvez com SIMD ou GPGPU, apenas para obter um pouco mais de desempenho. ;-)
— Paul R

7
Absolutamente real ao vivo aplicável. Ninguém jamais questionaria que foi um acidente nem um pouco.
— IFreilicht

5
Sou só eu ou é óbvio demais para perceber?
— Alvin Wong

3
@AlvinWong Eu não percebi imediatamente. Então, novamente, eu não uso C regularmente, ou qualquer outro idioma que descende do BCPL.
— Rhymoid

164

PHP

Não foi possível deixar isso para trás, então aqui está outro:

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

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

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

Na verdade, não é garantido que ele produza john, mas as chances são muito boas. Felizmente, o PHP aceita o que o / dev / random tem a oferecer, visto que (provavelmente) não pode analisá-lo e criar o número 0 bastante razoável. Afinal, alertar o programador sobre um erro em potencial é considerado um pecado mortal no PHP.


25
Você adora PHP - e, melhor ainda, às vezes raramente escolhe outra pessoa. Então, se você tiver sorte ela só vai parecer um pouco tendenciosa em primeiro lugar
— Falco

142
+1000 para "... alertar o programador sobre um erro em potencial é considerado um pecado mortal no PHP."
— jsedano


85

Haskell

É muito transparente se sempre retornar o mesmo nome, então tente o seguinte

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

Sempre que você quiser que seja aleatório:

[~]$ runghc prog.hs
Shuffling
Steve

[~]$ runghc prog.hs
Shuffling
Julie

E para o seu infeliz alvo:

[~]$ runhugs prog.hs
Shuffling
John

[~]$ runhugs prog.hs
Shuffling
John

O Hugs implementa apenas multitarefa cooperativa, portanto o rotatethread nunca será executado


24
Isso é diabólico!
— Daenyth

8
É como fotografar um dado que ainda não parou de se mover.
— Vi.

1
@Vi. Essa é uma boa analogia. Felizmente, o uso do MVars garante que a imagem não fique embaçada. :)
— monocell

@monocell Bem, tecnicamente, mesmo uma foto de um objeto em movimento pode ser clara.
— ghosts_in_the_code

75

Bash - simplicidade máxima

Um exemplo muito simples - vamos evitar problemas ao fazer o livro. Não se esqueça de semear o gerador do relógio do sistema para obter um bom resultado!

#!/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

Isso depende do usuário não saber o que o $SECONDSconstruído realmente faz; retorna o número de segundos desde o início do shell atual. Como está em um script, o shell sempre começou zero segundos atrás, então o gerador é sempre semeado 0e Julie sempre compra a cerveja.

Bônus:

Este resiste muito bem ao escrutínio; Se você digitar o mesmo código na linha de comando em vez de em um script, ele fornecerá resultados aleatórios, porque $SECONDSretornará o período de tempo em que o shell interativo do usuário esteve em execução.


9
\ o / Média !!! Realmente significa !!! $SECONDSftw! \ o /
— yeti

O que acontece se você fizer sourceisso, em vez de apenas executá-lo? O shebang ainda acionará uma nova concha ou algo assim?
— jpmc26

1
@ jpmc26: se você executá- sourcelo, é exatamente o mesmo que se você tivesse digitado os comandos na linha de comando; #! / bin / bash é um comentário, por isso é ignorado. Isso vale para qualquer script.
— Motim

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

Isso pode não enganar as pessoas que estão familiarizadas com a API .Net, mas as pessoas que não a conhecem podem acreditar que OrderBymodifica o objeto que você chama, e é um erro plausível para um novato na API.


1
Mesmo que o OrderBy hipoteticamente modificasse o objeto, essa chamada realmente classificaria a lista aleatoriamente? Como alguém não familiarizado com o .NET, meu primeiro palpite foi que, como rng.Next()é chamado apenas uma vez, a matriz seria classificada por uma constante, resultando em nenhuma alteração (ou uma alteração que depende apenas do algoritmo de classificação).
— Brilliand

1
@Brilliand O argumento passado para OrderBy não é um valor estático, é executado toda vez que um elemento é classificado e, nesse caso, retorna valores aleatórios sem comparar nenhum valor. Na verdade, funcionaria corretamente se a linha fosse #names = names.OrderBy(name => rng.Next());
— user3188175:

1
A =>indica que esta é uma expressão lambda C # (encerramento).
— Snowbody

44

PowerShell

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

Isso sempre será exibido John.

$namesé um System.Collections.Hashtableque não possui uma Lengthpropriedade. A partir do PowerShell v3, Length(e também Count) pode ser usado como uma propriedade em qualquer objeto. Se um objeto não tiver a propriedade, ele retornará 1quando o objeto não for nulo; caso contrário, ele retornará 0. Então, na minha resposta, $names.Lengthavalia como 1 e random -maximum 1sempre retorna 0, pois o máximo é exclusivo.


42

Q

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

Q sempre inicializa sua semente de número aleatório com o mesmo valor.


8
Então, basicamente, não é aleatório em tudo
— Sam Creamer

3
@SamCreamer O objetivo da pergunta é muito para tornar a saída não aleatória. Mas isso faz parecer aleatório por isso definitivamente se encaixa no projeto
— Cruncher

4
Desculpe, eu quis dizer que os números aleatórios de Q não são tão aleatórios, essa pergunta certamente atende aos critérios. Não quis me deparar com esse caminho!
— Sam Creamer

Sim, então você precisa encontrar seu próprio caminho para gerar uma semente aleatória toda vez que quiser usar o rand? Parece ... útil.
— DLeh

1
Pode definir a semente aleatória manualmente com muita facilidade ... iniciar o interpretador com a -S 1234opção ou fazer \S 1234a partir do intérprete
— skeevey

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

Impressões: Person X is buying: Jeff(onde X é de 0 a 4)

Abusar um pouco o contexto escalar. @index = int(rand() * 5)coloca um número inteiro aleatório de 0 a 4 na posição 0 da @indexlista. Ao imprimir a matriz, imprime corretamente o número inteiro aleatório em @index, mas ao usar como um índice de matriz em $people[@index]@index usa o contexto escalar, fornecendo o valor do tamanho da lista, ou seja 1.

Curiosamente, @people[@index]torna o índice corretamente.

Curiosamente, @people[@index]existe uma fatia de hash no Perl, e @indexé avaliada no contexto da lista; nesse caso, é uma lista de entradas únicas e é por isso que funciona corretamente


Então, em termos de C (++), há uma conversão implícita da lista em escalar, porque, durante a indexação, é esperado um escalar?
— IFreilicht

@iFreilicht Correct. No Perl, as expressões podem ser avaliadas como uma lista ou como escalar, dependendo de onde elas aparecem. Como resultado, a mesma expressão pode significar coisas diferentes, dependendo do contexto. Uma variável de lista (ou seja, uma variável com o @prefixo), no "contexto da lista", é interpretada como todos os seus elementos, mas no "contexto escalar", é um escalar igual ao número total de elementos na lista. Portanto, dentro da string, a variável list tem contexto de lista e é interpolada, e nós obtemos Person X is buying. Mas, como um índice da matriz, fica contexto escalar, e é interpretado como 1.
— Allen G

3
O problema é que, quando um programador Perl vê my @index = ..., ele imediatamente se pergunta "WTF ?!".
— 21814 derobert

@derobert, por que você se pergunta? Você vê um código como que, muitas vezes ... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words;etc
— Matthias

@ Matthias porque a linha é escolher e armazenar um único valor e, em vez de um escalar, ele está sendo armazenado em uma matriz.
— 26414 derobert

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

Ele sempre pega Julie.

Possui colchetes dentro dos colchetes, e o operador de vírgula retorna o valor do seu operando direito.
Também é muito fácil de perder. Eu já perdi isso antes em código real .


Isso é delicioso. Finalmente, um uso para aquele operador terrível e terrível.
— Keen

5
A vírgula nesse contexto é tecnicamente um operador, e não um separador. ecma-international.org/ecma-262/5.1/#sec-11.14 E é terrível. A menos que você queira que seu código seja difícil de ler. Como você faz aqui. Então, parabéns.
— Keen

2
@ Cory Sim, eu concordo - embora eu o use o tempo todo para o Code Golf com expressões de função (por exemplo (a,b)=>(a=b[0],b)). Eu esclareci minha resposta.
— Escova de dentes

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

O truque é que o método new Random().NextDouble()retorna um duplo entre 0 e 1. Ao aplicar Math.Floor()esse valor, ele sempre será 0.


24
Não resistiu ao meu olhar rápido. ;)
— Martin Ender

1
@TimS. Curtiu isso? : P
— Knerd 16/06

2
+1, muito melhor - eu sei o que você realmente está fazendo, mas isso pode enganar alguém que não conhece muito a API.
— Tim S.Jul

1
Eu não sei sobre isso. Se você estiver indo para especificar uma semente, por que não usar a maneira correta de conseguir um int "aleatório":var random = new Random(5); var id = random.NextInt(5);
— clcto

2
@clcto Na minha opinião, incluí-lo duas vezes é mais provável que alguém dê uma olhada dupla, pergunte o porquê e veja o problema. Incluir uma vez e depois incluir código desnecessário posteriormente fornece um pouco de redirecionamento / clandestinidade. Bônus: se alguém corrige um dos erros, existe outro.
— Tim S.

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

Dica:

Gere semente a partir do GUID. Guias têm 4 × 10-10 de chance de colisão. Super aleatório.

Responda:

Pelo menos quando você usa Guid.NewGuid(), gritos! (Maneira sorrateira de fazer sementes sempre 0). Também inútil (int) para direcionamento incorreto.


A outra maneira de fazer isso é ficar AddRangeconfuso Concatao adicionar nomes a um List<string>. Ocorreu-me ter um Hashset com um IEqualityComparer sorrateiro, mas seria muito incomum. No meu crédito, não havia muitas (se houver) respostas baseadas em sementes quando eu postei isso.
— Nathan Cooper

Acho que você teve a mesma ideia que eu, mas você foi um pouco mais rápido e dificultou a visão. +1!
— tsavinho 16/06

7
Semear o gerador de números aleatórios é um truque óbvio, mas você o escondeu de maneira brilhante aqui. Belo trabalho.
— TRiG

18

bash / coreutils

Isso é tirado quase literalmente de um script que escrevi para uma finalidade semelhante.

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

Mesmo esquecer de usar um R maiúsculo é um erro que cometi ocasionalmente em scripts da vida real.


3
você poderia dar uma explicação melhor? O atual é muito curto e não é útil para alguém que não está realmente familiarizado com o bash.
— IFreilicht

6
-respecifica a classificação reversa (lexicográfica), para que Steve sempre seja escolhido. Pode ser visto como um erro de digitação inocente -Rde tipo aleatório
— Max

3
Esse é um bom lembrete para não confiar nos comentários, mas ler atentamente o código!
— TecBrat

16

Rubi

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

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

Isso funcionaria corretamente sort_by, mas sortespera uma função de comparação que funcione como <=>. O resultado de rand () sempre será positivo, portanto sempre produzirá resultados equivalentes, desde que o sortalgoritmo da sua implementação Ruby seja determinístico. Meu Ruby 1.9.3 sempre gera Julie.


12

Rubi

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

puts names[rand() % 5]

rand() sem argumentos produz um float aleatório entre 0 e 1. Portanto, o módulo 5 não faz nada e, ao cortar em uma matriz com um argumento float, Ruby apenas o arredonda para baixo, então isso sempre retorna John.


11

Perl

três srands o tornarão três vezes mais aleatório!

#!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!";

explicação

não há $ RANDOM em perl, é uma variável indefinida. o código sempre retornará o primeiro elemento da lista - drinks em John :)

editar:

depois de passar pelo código, um dos cinco caras decidiu corrigir o erro óbvio, produzindo o seguinte programa:

#!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!";

você pode dizer quem fez isso apenas olhando o código?

explicação:

em Perl, $#arrayretorna o índice do último elemento; como matrizes são baseadas em zero, dada uma referência a uma matriz com cinco elementos, $#$aref_peopleserá 4.
randretorna um número aleatório maior ou igual a zero e menor que seu parâmetro, portanto nunca retornará 4, o que significa efetivamente que Julie nunca comprará bebidas :)


1
$RANDOMé um recurso real no bash, ksh e zsh (mas não no perl).
— kernigh

10

Pitão

Todo mundo sabe que você não pode confiar na aleatoriedade em um espaço de amostra tão pequeno; para torná-lo verdadeiramente aleatório, abandonei o método desatualizado de escolher um nome em uma lista e, em vez disso, meu programa soletrará um nome completamente aleatório. Como a maioria dos nomes no escritório tinha quatro letras, nós aceitaremos isso.

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)

Naturalmente, fiz alguns trabalhos de preparação para garantir a colheita da semente certa.


15
Semeando o número aleatório gerar com uma constante é muito óbvio ..
— Brendan Longo

@BrendanLong Definitivamente, levantaria as sobrancelhas. As pessoas querem testá-lo para garantir que seja aleatório. E quando não estiver, adivinhe quem está comprando bebidas.
— JFA 25/06

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

Desculpe Jeff!

Após algumas iterações, r == 1 mod 5, por causa da matemática. Moralidade: não escreva seu próprio PRNG se você é ruim em matemática. :)


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

O tamanho do vetor é realmente 1 devido aos parênteses usados ​​na lista de inicializadores. O operador de vírgula descartará todos os nomes e retornará o último, portanto, o comprador é sempre Roy.


10

Scala

Sei que meus usuários serão céticos, por isso incluí uma prova de que minha aleatoriedade é realmente justa!

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
  }

}

Um exemplo de execução:

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

A menos que alguém tenha muita sorte, John sempre comprará as bebidas.

A "prova" da aleatoriedade baseia-se no fato de que rand(1, 4) * rand(1, 4) % 5ainda é distribuído igualmente entre 1 e 4, inclusive. Mas rand(1, 5) * rand(1, 5) % 6é degenerado. Existe a possibilidade de você obter um 0, que tornaria o resultado final 0, independentemente do resto da "aleatoriedade".



9

Javascript

Segunda tentativa, essa é um pouco mais complicada:

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

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

A argumentsvariável é acessível localmente para funções e é uma matriz de todos os argumentos passados ​​para a função. Usando nomes simples e passando uma matriz para a própria função, você pode falsificar que não estamos comprando o comprimento da matriz, mas na verdade o comprimento da lista de argumentos (que é 1). Isso pode ser ainda melhor executado usando caracteres especiais ou um tipo de fonte.


Não foi o mais difícil de detectar. Qualquer pessoa que tenha construído uma Nfunção arbitrária -ary em JavaScript conhece a argumentsvariável.
— Conor O'Brien

8

C ++

Para ser justo, devemos executar muitas, muitas tentativas e escolher quem é escolhido com mais frequência.

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

Qual é o valor de 1<<31? Desculpe John.


A resposta para sua pergunta de spoiler é UB. Estou indeciso se isso faz é melhor ou pior.
— nwp 22/06

@nwp Bem, claro, mas ele mantém em qualquer lugar que int seja o complemento de 32 bits 2, o que parece ser o caso mesmo em 64 bits (com o gcc). Eu não testei no Clang, no entanto.
— fofo

Não, ele não acontece em nenhum lugar onde um int seja 32, mas o complemento de 2. O valor de 1 << 31 é indefinido. Você tem sorte, porém, um comportamento indefinido faz com que o compilador escolha o que quer que seja e, como é feito para acelerar, ele simplesmente decide não fazer nada, o que é o que você deseja.
— nwp 22/06

@nwp 1<<31 == 0x80000000não importa o que, pela própria definição de <<, e no complemento de 32 bits 2, seja isso INT_MIN. Você está pensando sobre o 1<<32que pode ou não == 0? (Porque em x86, 1<<32geralmente avalia a 1 ...)
— macios

@nwp Na verdade, é definido pela implementação. Agora, se nós estávamos falando sobre C, em seguida, seria indefinido.
— Stuart Olsen

7

T-SQL (2008+)

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

Explicação:

No MS SQL Server, RAND()avalia apenas uma vez por execução. Cada nome sempre recebe o mesmo número, deixando a ordem original. John é o primeiro. Suga para John.

Melhoria sugerida:

O T-SQL pode produzir números aleatórios por linha com qualidade decente RAND(CHECKSUM(NEWID())).


Eu acho que ORDER BY NEWID () será suficiente (não há necessidade de checksum)
— Jacob

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()é para fins de tempo, os.time()é o que deve ser usado math.randomseedpara um bom RNG. Infelizmente, Julie sempre compra (pelo menos no meu computador).


math.random()sem argumentos também retorna um número no intervalo [0,1). -1 por não entender isso.
— Mniip

@mniip: Verdadeiramente merecido também! Eu consertei agora.
— Kyle Kanos

6

Idiomatic C ++ 11

Quando as bebidas estão envolvidas, é especialmente importante estar atualizado com os mais recentes padrões e estilos de codificação; este é um ótimo exemplo de um seletor de nomes C ++ 11 altamente eficiente e compatível com o idioma.

Ele é propagado a partir do relógio do sistema e gera a semente junto com o nome para verificação a cada vez.

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

Experimente ao vivo: http://ideone.com/KOet5H

Ok, então isso realmente é um bom código geral; existem muitos arenques vermelhos para fazer você olhar muito de perto o código para perceber o óbvio - que o RNG nunca é realmente propagado :) Nesse caso, seedé apenas um número inteiro e, embora pareça, engineé passado como parâmetro para um função de propagação, na verdade é apenas ignorada. A variável seed é realmente definida a partir do relógio, para que possa ser impressa no final juntamente com o nome para adicionar insulto à lesão, mas ainda será sempre Steve quem compra as bebidas.


1
Me mata que não usa uma lista de inicializadores para os nomes. No mínimo, você definitivamente conseguiu fornecer código que parece superdimensionado. Eu não posso dizer se é por causa da "conformidade" ou todos os comentários de ruído: P
— vmrob

6

Javascript

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

Bem, desculpe, Math.randomnão aceita um parâmetro e sempre retornará um número de [0, 1). Ainda assim, é uma função variada feliz e não se queixa de argumentos!


5

Pitão

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 (aleatório) fornece uma string constante; não é um valor aleatório


6
Uma observação um tanto irrelevante: se você estiver usando o Python 3.2 ou posterior, o segundo argumento random.seed()deve ser 2(o padrão). Se você passar version=1, o hash()da string será usado como uma semente em vez de toda a string, e como o Python aleatoriamente distribui os valores de hash das strings a partir de 3.2, você obterá um nome realmente aleatório.
— Blacklight Shining

5

Perl

Emma era melhor não esquecer sua bolsa! Funciona sob stricte 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.

Explicação aqui .


O Perl 5.18 mudou um pouco isso, introduzindo a randomização da chave de hash (para evitar ataques de complexidade de colisão de hash).
— precisa saber é o seguinte

4

Javascript

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

O |0resultado é 0 o tempo todo, mas parece que ele está fazendo algum outro arredondamento.


Eu gosto disso. Embora eu faria parseInt(Math.random(0, 4))e talvez adicionar comentários como - Math.randomretorna uma dupla, então convertê-lo para um inteiro primeiro
— Claudiu

5
O truque é que, na verdade, Math.randomnão se importa com nossos poucos parâmetros. Ele escolhe os números à sua maneira. o |0está arredondando corretamente o resultado inesperado e, portanto, não é fonte de truques.
— Keen

|0é muito óbvio para alguns (provavelmente todos nós), mas aposto que há muitos que não têm ideia do que faz. Esse era o grupo em que eu estava confiando.
— Matt

3
@ Matt Quero dizer que |0, se você sabe o que faz, parece que está arredondando para baixo, e está arredondando para baixo, então não é um engano. (E se alguém não tem ideia do que |0faz, então não há utilidade para códigos enganosos; você pode apenas dizer a eles o que quiser que eles acreditem.) Em vez disso, o comportamento inesperado na sua resposta é baseado no fato de que Math.random(0,4)é funcionalmente idêntico a Math.random(), porque Math.randomnão usa parâmetros.
— Keen

4

J

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

Pobre Julie ... Curiosidades: esse pode ter sido o J mais limpo que eu já escrevi ...

Este código está realmente correto, exceto por uma coisa. ?.é o rng uniforme: ?.5sempre retornará 4. ?5estaria correto.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.