Script casuale che in realtà non è casuale


106

Come una piccola battuta in ufficio qualcuno voleva una sceneggiatura che scelga casualmente un nome e disse che avrebbe fatto un giro di drink.

Chiamiamo le persone John, Jeff, Emma, ​​Steve e Julie.

Ho pensato che sarebbe stato divertente creare una sceneggiatura che sembra casuale a colpo d'occhio, ma in realtà dà sempre la stessa persona dell'output (A te chi scegli).

La risposta più votata vince dopo una settimana

E il vincitore è....

Paul R con (attualmente) 158 voti.

Le risposte qui sono fantastiche e se qualcun altro ha altre idee su ciò che non è stato ancora pubblicato, per favore aggiungile, adoro leggerle.



6
@AstroCB uno dei miei preferiti. Proprio dietro i tavoli bobby.
Cruncher,

50
Sembra che sarebbe più subdolo se fosse casuale, tranne per non aver mai scelto una persona.
Brendan Long,

6
@AstroCB anche questo è fantastico: dilbert.com/strips/comic/2001-10-25
gilbertohasnofb

3
Ho esaminato la prima pagina: la maggior parte delle risposte sceglie sempre John, il 2 ° più alto è Julie, Jeff viene scelto raramente e Steve da 1. Anche Ray è stato scelto da uno, ma nessuno ha scelto Emma. Morale della storia: quando sei in fila per decidere a caso chi comprerà le bevande, chiamati Emma.
Miserabile variabile,

Risposte:


171

C

È importante decidere chi sta acquistando il più rapidamente possibile, in modo da non perdere tempo prezioso per bere - quindi C è la scelta ovvia per ottenere le massime prestazioni:

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

Spiegazione:

Funzionerebbe perfettamente se ci fosse un break;caso dopo nell'istruzione switch. Comunque sia, ogni caso "passa" al successivo, così la povera Julie finisce sempre per comprare le bevande.


17
+1 per le prestazioni - molto più veloce del lancio di un dado fisico! ;)
Jwosty,

16
Sto pensando di ottimizzarlo ulteriormente, forse con SIMD o GPGPU, solo per ottenere un po 'più di prestazioni. ;-)
Paul R,

7
Assolutamente reale dal vivo applicabile. Nessuno avrebbe mai nemmeno messo in dubbio che si trattasse di un incidente.
iFreilicht,

5
Sono solo io o è troppo ovvio per individuarlo?
Alvin Wong,

3
@AlvinWong non me ne sono accorto subito. Poi di nuovo, non uso C regolarmente, o qualsiasi altra lingua che discenda da BCPL.
Rhymoid,

164

PHP

Non potevo lasciarlo andare, quindi eccone un altro:

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

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

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

Questo in realtà non è garantito per produrre John, ma le possibilità sono molto buone. PHP prenderà felicemente tutto ciò che / dev / random ha da offrire, visto che (probabilmente) non può analizzarlo e trovare invece il numero molto ragionevole 0. Dopotutto, avvisare il programmatore di un potenziale errore è considerato un peccato mortale in PHP.


25
Devi amare PHP - e ancora meglio, a volte raramente sceglierà qualcun altro. Quindi, se sei fortunato, all'inizio sembrerà un po 'distorto
Falco,

142
+1000 per "... avvisare il programmatore di un potenziale errore è considerato un peccato mortale in PHP."
jsedano,


85

Haskell

È troppo trasparente se restituisce sempre lo stesso nome, quindi prova quanto segue

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

Ogni volta che vuoi che sia casuale:

[~]$ runghc prog.hs
Shuffling
Steve

[~]$ runghc prog.hs
Shuffling
Julie

E per il tuo sfortunato obiettivo:

[~]$ runhugs prog.hs
Shuffling
John

[~]$ runhugs prog.hs
Shuffling
John

Gli abbracci implementano solo il multitasking cooperativo, quindi il rotatethread non funzionerà mai


24
È diabolico!
Daenyth,

8
Sembra di fotografare un dado che non ha ancora smesso di muoversi.
Vi.

1
@Vi. Questa è una bella analogia. Fortunatamente l'uso di MVars garantisce che l'immagine non sarà sfocata. :)
monocell

@monocell Beh, tecnicamente, anche una foto di un oggetto in movimento può essere chiara.
ghosts_in_the_code

75

Bash: massima semplicità

Un esempio molto semplice: evitiamo qualsiasi problema facendolo come da manuale. Non dimenticare di seminare il generatore dall'orologio di sistema per un buon risultato!

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

Questo si basa sul fatto che l'utente non sa cosa $SECONDSfa effettivamente il built-in; restituisce il numero di secondi dall'avvio della shell corrente. Come in una sceneggiatura, la shell è sempre iniziata zero secondi fa, quindi il generatore viene sempre seminato 0e Julie compra sempre la birra.

Bonus:

Questo resiste abbastanza bene al controllo; Se si immette lo stesso codice sulla riga di comando anziché in uno script, si otterranno risultati casuali, poiché $SECONDSrestituirà il periodo di tempo durante il quale la shell interattiva dell'utente è stata in esecuzione.


9
\ o / Mean !!! Veramente meschino!!! $SECONDSftw! \ o /
yeti,

Cosa succede se sourcequesto, invece di eseguirlo? Lo shebang scatenerà ancora un nuovo guscio o qualcosa del genere?
jpmc26,

1
@ jpmc26: se lo esegui, sourceè esattamente lo stesso di se avessi digitato tu stesso i comandi sulla riga di comando; #! / bin / bash è un commento, quindi viene ignorato. Questo vale per qualsiasi sceneggiatura.
Riot

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

Questo potrebbe non ingannare le persone che hanno familiarità con l'API .Net, ma le persone che non lo conoscono potrebbero credere che OrderBymodifichi l'oggetto su cui lo chiami, ed è un errore plausibile per un neofita dell'API da fare.


1
Anche se OrderBy avesse ipoticamente modificato l'oggetto, quella chiamata ordinerebbe effettivamente l'elenco in modo casuale? Come qualcuno che non ha familiarità con .NET, la mia prima ipotesi è stata che, poiché rng.Next()viene chiamato solo una volta, l'array verrà ordinato in base a una costante, senza risultati (o cambiamenti che dipendono solo dall'algoritmo di ordinamento).
Brilliand,

1
@Brilliand L'argomento passato a OrderBy non è un valore statico, viene eseguito ogni volta che un elemento viene ordinato e in questo caso restituisce valori casuali senza confrontare alcun valore. names = names.OrderBy(name => rng.Next());
Funzionerebbe

1
Il =>indica che si tratta di un C # lambda espressione (chiusura).
Snowbody,

44

PowerShell

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

Questo emetterà sempre John.

$namesè un oggetto System.Collections.Hashtableche non ha Lengthproprietà. A partire da PowerShell v3, Length(e anche Count) può essere utilizzato come proprietà su qualsiasi oggetto. Se un oggetto non ha la proprietà, ritornerà 1quando l'oggetto non è nullo, altrimenti tornerà 0. Quindi, nella mia risposta, $names.Lengthvaluta come 1 e random -maximum 1restituisce sempre 0 poiché il massimo è esclusivo.


42

Q

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

Q inizializza sempre il seme del numero casuale con lo stesso valore.


8
quindi in pratica non è affatto casuale
Sam Creamer,

3
@SamCreamer Lo scopo della domanda è molto di rendere l'output non casuale. Ma questo sembra casuale quindi si adatta perfettamente al conto
Cruncher,

4
Spiacenti, intendevo dire che i numeri casuali di Q non sono così casuali, questa domanda soddisfa sicuramente i criteri. Non intendevo imbattermi in quel modo!
Sam Creamer,

Sì, quindi devi trovare il tuo modo di generare un seme casuale ogni volta che vuoi usare rand? Sembra ... utile.
DLeh,

1
Può impostare manualmente il seme casuale molto facilmente ... avvia l'interprete con l' -S 1234opzione o \S 1234
esegui

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

Stampe: Person X is buying: Jeff(dove X è 0-4)

Abusa un po 'del contesto scalare. @index = int(rand() * 5)posiziona un numero intero casuale compreso tra 0 e 4 nella posizione 0 @indexdell'elenco. Quando si stampa l'array, stampa correttamente l'intero intero in @index, ma quando si utilizza come indice dell'array in $people[@index], @index utilizza il contesto scalare, dandogli il valore della dimensione dell'elenco, ad es 1.

Abbastanza interessante, lo @people[@index]fa indicizzare correttamente.

È interessante notare che @people[@index]una fetta di hash in Perl, quindi @indexviene valutata nel contesto dell'elenco; in questo caso, è un unico elenco di voci ed è per questo che funziona correttamente


Quindi, in termini di C (++), c'è una conversione implicita dall'elenco allo scalare perché durante l'indicizzazione è previsto uno scalare?
iFreilicht,

@iFreilicht Correct. In Perl, le espressioni possono essere valutate come un elenco o come uno scalare, a seconda di dove appaiono. Di conseguenza, la stessa espressione potrebbe significare cose diverse, a seconda del contesto. Una variabile di elenco (ovvero una variabile con il @prefisso), in "contesto elenco", viene interpretata come tutti i suoi elementi, ma in "contesto scalare" è uno scalare uguale al numero totale di elementi nell'elenco. Quindi, all'interno della stringa, la variabile list ha il contesto list e viene interpolata, e otteniamo Person X is buying. Ma come indice di matrice, ottiene un contesto scalare e viene interpretato come 1.
Allen G

3
Il problema è che quando vede un programmatore Perl my @index = ..., si chiede subito "WTF ?!".
derobert,

@derobert, perché ti chiedi? Vedi un codice del genere abbastanza spesso ... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words;ecc.
Matthias,

@Matthias perché la riga deve selezionare e archiviare un singolo valore e invece di uno scalare viene archiviata in un array.
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]);

Prende sempre Julie.

Ha parentesi quadre tra parentesi quadre e l'operatore virgola restituisce il valore del suo operando destro.
È anche molto facile perdere. L'ho perso prima nel vero codice.


Questo è delizioso. Finalmente un uso per quel terribile, terribile operatore.
Appassionato il

5
La virgola in quel contesto è tecnicamente un operatore, piuttosto che un separatore. ecma-international.org/ecma-262/5.1/#sec-11.14 Ed è terribile. A meno che tu non voglia che il tuo codice sia difficile da leggere. Come fai qui. Quindi, complimenti.
Appassionato il

2
@Cory Sì, sono d'accordo - anche se lo uso sempre per Code Golf con espressioni di funzione (ad es (a,b)=>(a=b[0],b).). Ho chiarito la mia risposta.
Spazzolino da denti,

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

Il trucco è che il metodo new Random().NextDouble()restituisce un doppio tra 0 e 1. Applicando Math.Floor()questo valore, sarà sempre 0.


24
Non ha resistito al mio rapido sguardo. ;)
Martin Ender,

1
@TimS. come quello? : P
Knerd,

2
+1, molto meglio: so cosa stai davvero facendo, ma potrebbe ingannare qualcuno che non ha familiarità con l'API.
Tim S.

1
Non lo so. Se hai intenzione di specificare un seme, perché non usare semplicemente il modo corretto di ottenere un int "casuale":var random = new Random(5); var id = random.NextInt(5);
clcto

2
@clcto Secondo me, includerlo due volte è più probabile che qualcuno faccia un doppio tentativo, chieda perché e vedi il problema. Includerlo una volta e quindi includere il codice non necessario in seguito, dà un po 'di reindirizzamento / subdolezza. Bonus: se qualcuno corregge uno dei bug, ne esiste un altro.
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]);

Suggerimento:

Genera seme dal GUID. Le guide hanno una probabilità di collisione 4 × 10-10. Super casuale.

Risposta:

Almeno quando usi Guid.NewGuid(), whoops! (Modo subdolo per rendere sempre il seme 0). Anche inutile (int) per direzionare male.


L'altro modo in cui potrei farlo, è AddRangeconfondermi con l' Concataggiunta di nomi a List<string>. Mi è venuto in mente di avere un Hashset con un IEqualityComparer subdolo, ma sarebbe troppo insolito. Nel mio merito non c'erano molte (se presenti) risposte basate sul seme quando ho pubblicato questo.
Nathan Cooper,

Immagino che tu abbia avuto la stessa idea di me, ma eri un po 'più veloce e lo rendevi un po' più difficile da vedere. +1!
Tsavinho,

7
Seminare il generatore di numeri casuali è un trucco ovvio, ma l'hai nascosto brillantemente qui. Bel lavoro.
TRiG

18

bash / coreutils

Questo è preso quasi alla lettera da una sceneggiatura che ho scritto per uno scopo simile.

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

Anche dimenticare di usare la maiuscola R è un errore che ho fatto occasionalmente negli script della vita reale.


3
potresti dare una spiegazione migliore? Il tuo attuale è davvero breve e non utile a qualcuno che non ha molta familiarità con Bash.
iFreilicht,

6
-rspecifica l'ordinamento inverso (lessicografico), quindi Steve verrà sempre selezionato. Potrebbe essere visto come un errore di battitura innocente -Rper tipo casuale
Max

3
Questo è un buon promemoria per non fidarti dei commenti, ma per leggere attentamente il codice!
TecBrat,

16

Rubino

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

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

Funzionerebbe correttamente con sort_by, ma si sortaspetta una funzione di confronto che funzioni come <=>. Il risultato di rand () sarà sempre positivo, quindi produrrà sempre risultati equivalenti a condizione che l' sortalgoritmo dell'implementazione di Ruby sia deterministico. Il mio Ruby 1.9.3 genera sempre Julie.


12

Rubino

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

puts names[rand() % 5]

rand() senza argomenti produce un float casuale tra 0 e 1. Quindi modulo 5 non fa nulla, e quando si suddivide in un array con un argomento float Ruby lo arrotonda per difetto, quindi questo restituisce sempre John.


11

Perl

tre srandsecondi lo renderanno tre volte più casuale!

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

spiegazione

non c'è $ RANDOM in perl, è una variabile indefinita. il codice restituirà sempre il primo elemento dall'elenco - bevande su John :)

modificare:

dopo aver esaminato il codice, uno dei cinque ragazzi ha deciso di correggere l'errore evidente, producendo il seguente programma:

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

puoi dire chi è stato semplicemente guardando il codice?

spiegazione:

in Perl, $#arrayrestituisce l'indice dell'ultimo elemento; poiché le matrici sono a base zero, dato un riferimento a una matrice con cinque elementi, $#$aref_peoplesarà 4.
randrestituisce un numero casuale maggiore o uguale a zero e inferiore al suo parametro, quindi non tornerà mai 4, il che significa che Julie non acquisterà mai bevande :)


1
$RANDOMè una caratteristica reale in bash, ksh e zsh (ma non in perl).
kernigh,

10

Pitone

Tutti sanno che non puoi fidarti della casualità in un così piccolo spazio campione; per renderlo davvero casuale, ho abbandonato il metodo obsoleto di scegliere un nome da un elenco e invece il mio programma scriverà un nome completamente casuale. Poiché la maggior parte dei nomi nell'ufficio aveva 4 lettere, ci accontenteremo di questo.

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, ho fatto un lavoro di preparazione per assicurarmi di scegliere il seme giusto.


15
Vedere il numero casuale generato con una costante è troppo ovvio ...
Brendan Long,

@BrendanLong Solleverebbe sicuramente le sopracciglia. La gente vorrebbe testarlo per assicurarsi che sia casuale. E quando non lo è, indovina chi compra bevande.
JFA,

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

Scusa Jeff!

Dopo alcune iterazioni r == 1 mod 5, a causa della matematica. Moralità: non scrivere il tuo PRNG se sei cattivo in matematica. :)


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

La dimensione del vettore è in realtà 1 a causa della parentesi utilizzata nell'elenco di inizializzatori. L'operatore virgola eliminerà tutti i nomi e restituirà l'ultimo, quindi l'acquirente è sempre Roy.


10

Scala

So che i miei utenti saranno scettici, quindi ho incluso una prova che la mia casualità è veramente giusta!

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
  }

}

Una corsa di esempio:

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

A meno che qualcun altro non sia estremamente fortunato, John comprerà sempre le bevande.

La "prova" della casualità si basa sul fatto che rand(1, 4) * rand(1, 4) % 5è ancora uniformemente distribuito tra 1 e 4, compreso. Ma rand(1, 5) * rand(1, 5) % 6è degenerato. C'è la possibilità di ottenere uno 0, che quindi renderebbe il risultato finale 0 indipendentemente dal resto della "casualità".



9

JavaScript

Secondo tentativo, questo è un po 'più complicato:

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

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

La argumentsvariabile è accessibile localmente per le funzioni ed è una matrice di tutti gli argomenti passati alla funzione. Utilizzando la semplice denominazione e passando un array alla funzione stessa, è possibile falsificare che non stiamo prendendo la lunghezza dell'array, ma in effetti la lunghezza dell'elenco degli argomenti (che è 1). Questo può essere eseguito anche meglio usando caratteri speciali o un tipo di carattere.


Questo non è stato il più difficile da individuare. Chiunque abbia Ncreato una funzione arbitraria in JavaScript sa della argumentsvariabile.
Conor O'Brien,

8

C ++

Per essere onesti dovremmo fare molte, molte prove e scegliere chi viene selezionato più spesso.

#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 è il valore di 1<<31? Scusa, John.


La risposta alla tua domanda sullo spoiler è UB. Sono indeciso se questo è meglio o peggio.
nwp,

@nwp Bene, certo, ma contiene ovunque che int sia il complemento a 32 bit 2, il che sembra essere il caso anche su 64 bit (con gcc). Non ho ancora testato su Clang.
soffice

No, non tiene da nessuna parte dove un int è un complemento di 32 ma 2. Il valore di 1 << 31 non è definito. Sei fortunato, però, un comportamento indefinito fa sì che il compilatore scelga quello che sembra e dato che è fatto per la velocità, deciderà semplicemente di non fare nulla, che sembra essere quello che vuoi.
nwp,

@nwp, 1<<31 == 0x80000000non importa cosa, per definizione <<, e sul complemento a 32 bit 2, questo è INT_MIN. Stai forse pensando a 1<<32quale può o no == 0? (Perché su x86, di 1<<32solito restituisce 1 ...)
soffice

@nwp In realtà è definito dall'implementazione. Ora, se stessimo parlando di C, allora non sarebbe definito.
Stuart Olsen,

7

T-SQL (2008+)

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

Spiegazione:

In MS SQL Server, RAND()valuta solo una volta per esecuzione. A ogni nome viene sempre assegnato lo stesso numero, lasciando l'ordine originale. John è il primo. Fa schifo per John.

Miglioramento suggerito:

T-SQL può produrre numeri casuali di buona qualità per riga con RAND(CHECKSUM(NEWID())).


Penso che ORDER BY NEWID () sarà sufficiente (non è necessario 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()è a scopo di cronometraggio, os.time()è ciò che dovrebbe essere usato math.randomseedper un buon RNG. Purtroppo, Julie compra sempre (almeno sul mio computer).


math.random()senza argomenti restituisce anche un numero nell'intervallo [0,1). -1 per non averlo capito.
mniip,

@mniip: anche meritato! L'ho risolto ora.
Kyle Kanos,

6

C ++ idiomatico 11

Quando sono coinvolte le bevande, è particolarmente importante essere aggiornati con gli standard e gli stili di codifica più recenti; questo è un ottimo esempio di un selettore di nomi C ++ 11 altamente efficiente e conforme al linguaggio.

Viene eseguito il seeding dall'orologio di sistema e restituisce il seed insieme al nome per la verifica ogni volta.

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

Prova questo dal vivo: http://ideone.com/KOet5H

Ok, quindi in realtà questo è un codice abbastanza buono nel complesso; ci sono molte aringhe rosse per farti guardare troppo da vicino il codice per notare l'ovvio - che l'RNG non è mai realmente seedato :) In questo caso seedè solo un numero intero e mentre sembra che enginesia passato come parametro a un funzione seeding, in realtà è appena ignorato. La variabile seed è davvero impostata dall'orologio, quindi può essere emessa alla fine insieme al nome per aggiungere insulto all'infortunio, ma sarà sempre Steve a comprare le bevande.


1
Mi uccide che non usa un elenco di inizializzatori per i nomi. Per lo meno, sei sicuramente riuscito a fornire codice che sembra troppo ingegnerizzato. Non so dire se sia a causa della "conformità" o di tutti i commenti sul rumore: P
vmrob

6

JavaScript

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

Beh, scusa, Math.randomnon accetta un parametro e restituirà sempre un numero da [0, 1). Tuttavia, è una felice funzione variadica e non si lamenta degli argomenti!


5

Pitone

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) dà una stringa costante; non un valore casuale


6
Una nota in qualche modo irrilevante: se si utilizza Python 3.2 o versioni successive, il secondo argomento random.seed()deve essere 2(impostazione predefinita). Se passi version=1, la hash()stringa verrà utilizzata come seme anziché l'intera stringa e poiché Python esegue il seeding casuale dei valori di hash delle stringhe a partire da 3.2, otterrai un nome realmente casuale.
Blacklight Shining,

5

Perl

È meglio che Emma non dimentichi la sua borsa! Funziona con 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.

Spiegazione qui .


Perl 5.18 ha cambiato un po 'questo, introducendo la randomizzazione della chiave hash (per evitare attacchi di complessità della collisione hash).
Konrad Borowski il

4

JavaScript

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

Il |0risultato è sempre 0 ma sembra che stia facendo qualche altro arrotondamento.


Mi piace. Anche se lo farei parseInt(Math.random(0, 4))e forse aggiungerei commenti come - Math.randomrestituisce un doppio, quindi prima convertilo in un numero intero
Claudiu

5
Il trucco è in realtà che Math.randomnon importa nulla per i nostri parametri magri. Scegli i numeri a modo suo. la |0è correttamente arrotondando il risultato inaspettato, e quindi non è una fonte di qualsiasi inganno.
Appassionato il

|0è molto ovvio per alcuni (tutti noi molto probabilmente), ma scommetto che ci sono molte persone che non hanno idea di cosa faccia. Questo è il gruppo su cui facevo affidamento.
Matt,

3
@Matt Voglio dire che |0, se sai cosa fa, sembra che si stia arrotondando , e che stia arrotondando, quindi non è un inganno. (E se qualcuno non ha idea di cosa |0faccia, allora non serve a nulla per il codice ingannevole; puoi semplicemente dire loro qualunque cosa tu voglia far credere.) Invece, il comportamento imprevisto nella tua risposta si basa sul fatto che Math.random(0,4)è funzionalmente identico a Math.random(), perché Math.randomnon usa parametri.
Appassionato il

4

J

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

Povera Julie ... Curiosità: questo potrebbe essere stato il J più pulito che abbia mai scritto ...

Questo codice è in realtà corretto, tranne una cosa. ?.è l'uniform rng: ?.5tornerà sempre 4. ?5sarebbe stato corretto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.