Случайный сценарий, который на самом деле не случайный


106

В качестве маленькой шутки в офисе кто-то захотел сценарий, который случайным образом выбирает имя, и сказал, что человек сделает несколько напитков.

Давайте назовем людей Джоном, Джеффом, Эммой, Стивом и Джули.

Я подумал, что было бы забавно создать сценарий, который на первый взгляд кажется случайным, но на самом деле всегда дает одного и того же человека в качестве выходных данных (до вас, кого вы выберете).

Ответ с наибольшим количеством голосов побеждает через неделю

И победитель....

Пол Р. с (в настоящее время) 158 голосами.

Ответы здесь замечательные, и если у кого-то еще есть какие-либо идеи, которые еще не были опубликованы, пожалуйста, добавьте их, я люблю читать их.



6
@AstroCB один из моих любимых. Прямо за бобби столами.
— Cruncher

50
Кажется, что было бы подлее, если бы оно было случайным, за исключением того, что никогда не выбираешь одного человека.
— Восстановить Монику

6
@AstroCB это тоже фантастика: dilbert.com/strips/comic/2001-10-25
— gilbertohasnofb

3
Я прошел первую страницу: большинство ответов всегда выбирают Джона, 2-е место - Джули, Джефф выбирается редко, а Стив - 1. Даже Рэй был выбран одним, но никто не выбрал Эмму. Мораль истории: стоя в очереди, чтобы случайным образом решить, кто будет покупать напитки, назовите себя Эммой.
— Ужасная переменная

Ответы:


171

С

Важно решить, кто покупает, как можно быстрее, чтобы не тратить драгоценное время на питье - поэтому C является очевидным выбором для достижения максимальной производительности:

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

Объяснение:

Это работало бы отлично, если бы в break;каждом операторе switch был символ после каждого. Как бы то ни было, каждый случай «проваливается» на следующий, поэтому бедная Джули всегда заканчивает тем, что покупает напитки.


17
+1 за производительность - намного быстрее, чем бросить физический кубик! ;)
— Jwosty

16
Я думаю о дальнейшей оптимизации, возможно, с SIMD или GPGPU, просто чтобы немного повысить производительность. ;-)
— Пол Р

7
Абсолютно реальная жизнь применима. Никто даже не усомнится в том, что это был несчастный случай.
— iFreilicht

5
Это только я или это слишком очевидно, чтобы заметить?
— Элвин Вонг

3
@ AlvinWong Я не сразу это заметил. Опять же, я не использую C регулярно или любой другой язык, который произошел от BCPL.
— Рифмоид

164

PHP

Не мог отпустить это, так вот еще один:

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

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

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

На самом деле это не гарантировано, чтобы произвести Джона, но шансы очень хороши. PHP с радостью примет все, что может предложить / dev / random, чтобы увидеть, что он (вероятно) не может его проанализировать, и вместо этого придумает очень разумное число 0. В конце концов, предупреждение программиста о потенциальной ошибке считается смертельным грехом в PHP.


25
Вы должны любить PHP - и даже лучше, он будет редко выбирать кого-то другого. Так что если вам повезет, на первый взгляд это будет немного предвзято
— Falco

142
+1000 за «... оповещение программиста о потенциальной ошибке считается смертельным грехом в PHP».
— Jsedano


85

Haskell

Он слишком прозрачен, если всегда возвращает одно и то же имя, поэтому попробуйте следующее

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

Всякий раз, когда вы хотите, чтобы это было случайно:

[~]$ runghc prog.hs
Shuffling
Steve

[~]$ runghc prog.hs
Shuffling
Julie

И для вашей неудачной цели:

[~]$ runhugs prog.hs
Shuffling
John

[~]$ runhugs prog.hs
Shuffling
John

Hugs реализует только совместную многозадачность, поэтому rotateпоток никогда не запустится


24
Это дьявольское!
— Daenyth

8
Похоже на фотографирование кости, которая еще не остановилась.
— Ви.

1
@Vi. Это хорошая аналогия. К счастью, использование MVars гарантирует, что изображение не будет размытым. :)
— одноячейка

@monocell Технически, даже фотография движущегося объекта может быть четкой.
— ghosts_in_the_code

75

Баш - максимальная простота

Очень простой пример - давайте избежим каких-либо проблем, выполняя это учебным путем. Не забудьте запустить генератор от системных часов для хорошего результата!

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

Это зависит от того, что пользователь не знает, что на $SECONDSсамом деле делает встроенная программа; он возвращает количество секунд с момента запуска текущей оболочки. Как и в сценарии, оболочка всегда запускалась ноль секунд назад, поэтому генератор всегда засеян, 0а Джули всегда покупает пиво.

Бонус:

Этот выдерживает проверку довольно хорошо; Если вы введете один и тот же код в командной строке, а не в сценарии, он даст случайные результаты, потому что $SECONDSбудет возвращать время, в течение которого была запущена интерактивная оболочка пользователя.


9
\ о / значит !!! На самом деле означает!!! $SECONDSFTW! \ o /
— йети

Что произойдет, если вы sourceэто сделаете , вместо того, чтобы просто выполнить это? Будет ли Шебанг все еще вызывать новую оболочку или что-то?
— jpmc26

1
@ jpmc26: если вы выполните его с помощью команды, sourceто это точно так же, как если бы вы вводили команды в командной строке самостоятельно; #! / bin / bash - это комментарий, поэтому он игнорируется. Это верно для любого сценария.
— Бунт

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

Это может не обмануть людей, знакомых с .Net API, но люди, которые не знают его, могут поверить, что OrderByизменяет вызываемый вами объект, и для новичка в API это правдоподобная ошибка.


1
Даже если бы OrderBy гипотетически изменил объект, действительно ли этот вызов отсортировал бы список случайным образом? Как человек, незнакомый с .NET, я предположил, что, поскольку он rng.Next()вызывается только один раз, массив будет отсортирован по константе, что не приведет к изменению (или изменению, которое зависит только от алгоритма сортировки).
— Brilliand

1
@Brilliand Аргумент, переданный в OrderBy, не является статическим значением, он выполняется каждый раз, когда элемент сортируется, и в этом случае возвращает случайные значения без сравнения каких-либо значений. Это на самом деле будет работать правильно, если строка былаnames = names.OrderBy(name => rng.Next());
— user3188175

1
=>Указывает на то, что это лямбда - выражение в C # (закрытие).
— Snowbody

44

PowerShell

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

Это будет всегда выводить John.

$namesэто System.Collections.Hashtableне имеет Lengthсвойства. Начиная с PowerShell v3, Length(а также Count) можно использовать как свойство любого объекта. Если у объекта нет свойства, он вернется, 1когда объект не равен нулю, иначе он вернется 0. Поэтому в моем ответе $names.Lengthоценивается как 1 и random -maximum 1всегда возвращает 0, так как максимум является исключительным.


42

Q

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

Q всегда инициализирует начальное число случайных чисел одним и тем же значением.


8
так что в принципе это совсем не случайно
— Сэм Кример

3
@SamCreamer Цель вопроса - сделать вывод неслучайным. Но это выглядит случайным, так что это определенно отвечает всем требованиям
— Cruncher

4
Извините, я имел в виду, что случайные числа Q не настолько случайны, этот вопрос, безусловно, соответствует критериям. Не хотел встретить этот путь!
— Сэм Кример

Да, так вы должны найти свой собственный способ генерировать случайное семя каждый раз, когда вы хотите использовать rand? Звучит ... полезно.
— DLeh

1
Можно очень легко установить случайное начальное число вручную ... запустить интерпретатор с помощью -S 1234опции или сделать \S 1234из интерпретатора
— 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";

Печатает: Person X is buying: Jeff(где X от 0 до 4)

немного злоупотребляет скалярным контекстом. @index = int(rand() * 5)помещает случайное целое число от 0 до 4 в 0-ю позицию @indexсписка. При печати массива он правильно печатает случайное целое число в @index, но при использовании в качестве индекса массива в $people[@index]@index используется скалярный контекст, присваивая ему значение размера списка, т.е.1 .

Достаточно интересно, @people[@index] делает это правильно индексировать.

Интересно, @people[@index]что в Perl есть фрагмент хеша, поэтому @indexон оценивается в контексте списка; в данном случае это один список записей, и поэтому он работает правильно


Таким образом, в терминах C (++) происходит неявное преобразование из списка в скаляр, потому что при индексации скаляр ожидается?
— iFreilicht

@iFreilicht Правильно. В Perl выражения могут оцениваться как список или скаляр, в зависимости от того, где они появляются. В результате одно и то же выражение может означать разные вещи, в зависимости от контекста. Переменная списка (то есть переменная с @префиксом) в «контексте списка» интерпретируется как все ее элементы, но в «скалярном контексте» это скаляр, равный общему количеству элементов в списке. Следовательно, внутри строки переменная списка имеет контекст списка и интерполируется, и мы получаем Person X is buying. Но как индекс массива, он получает скалярный контекст и интерпретируется как 1.
— Аллен Дж.

3
Проблема в том, что когда программист Perl видит my @index = ..., он сразу же задается вопросом «WTF ?!».
— Дероберт

@derobert, с чего бы тебе удивляться? Вы видите такой код довольно часто ... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words;и т.д.
— Матиас

@Matthias, потому что строка предназначена для выбора и хранения одного значения, а вместо скаляра оно сохраняется в массиве.
— Дероберт

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

Это всегда выбирает Джули.

Он заключен в квадратные скобки, а оператор запятой возвращает значение своего правого операнда.
Это также очень легко пропустить. Я пропустил это раньше в реальном коде.


Это восхитительно. Наконец, использование для этого ужасного, ужасного оператора.
— Кин

5
Запятая в этом контексте технически является оператором, а не разделителем. ecma-international.org/ecma-262/5.1/#sec-11.14 И это ужасно. Если только вы не хотите, чтобы ваш код был трудным для чтения. Как вы делаете здесь. Итак, слава.
— Кин

2
@ Кори Да, я согласен - хотя я все время использую его для Code Golf с функциональными выражениями (например (a,b)=>(a=b[0],b)). Я уточнил свой ответ.
— Зубная щетка

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

Хитрость в том, что метод new Random().NextDouble()возвращает двойное значение от 0 до 1. Применяя Math.Floor()это значение, оно всегда будет 0.


24
Это не выдержало моего быстрого взгляда. ;)
— Мартин Эндер

1
@TimS. как это? : P
— Knerd

2
+1, намного лучше - я знаю, что вы на самом деле делаете, но это может обмануть кого-то, кто не слишком знаком с API.
— Тим С.

1
Я не знаю об этом. Если вы собираетесь указать начальное число, почему бы просто не использовать правильный способ получения «случайного» int:var random = new Random(5); var id = random.NextInt(5);
— clcto

2
@clcto По моему мнению, включение его в два раза с большей вероятностью заставит кого-то сделать двойной дубль, спросить почему и увидеть проблему. Включение его один раз, а затем включение ненужного кода дает немного перенаправления / скрытности. Бонус: если кто-то исправляет одну из ошибок, существует другая.
— Тим С.

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

Подсказка:

Генерация семян из GUID. Гиды имеют шанс столкновения 4 × 10-10. Супер случайный.

Ответ:

По крайней мере, когда вы используете Guid.NewGuid(), упс! (Подлый способ сделать семя всегда 0). Также бессмысленно (int) для неправильного направления.


Другой способ , которым я мог бы это сделать, чтобы получить AddRangeзапутались с Concatпри добавлении имен к List<string>. Мне приходило в голову иметь Hashset с хитрым IEqualityComparer, но это было бы слишком необычно. На мой счет не было много (если таковые имеются) основанные на семени ответы, когда я отправил это.
— Натан Купер

Я предполагаю, что у вас была та же идея, что и у меня, но вы были немного быстрее и сделали ее немного труднее увидеть. +1!
— цавиньо

7
Заполнение генератора случайных чисел - очевидный трюк, но вы блестяще спрятали его здесь. Прекрасная работа.
— TRiG

18

bash / coreutils

Это почти дословно взято из сценария, который я написал для аналогичной цели.

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

Даже забыв использовать верхний регистр R, я ошибаюсь в реальных сценариях.


3
не могли бы вы дать лучшее объяснение? Ваш текущий очень короткий и не полезен для тех, кто не очень знаком с bash.
— iFreilicht

6
-rопределяет обратную (лексикографическую) сортировку, поэтому Стив всегда будет выбран. Это можно рассматривать как невинную опечатку -Rдля случайной сортировки
— Макс

3
Это хорошее напоминание не доверять комментариям, а внимательно читать код!
— TecBrat

16

Рубин

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

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

Это будет работать правильно sort_by, но sortожидает функция сравнения, которая работает как <=>. Результат rand () всегда будет положительным, поэтому он всегда будет давать эквивалентные результаты, если sortалгоритм вашей реализации Ruby является детерминированным. Мой Ruby 1.9.3 всегда выводит Джули.


12

Рубин

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

puts names[rand() % 5]

rand() без аргументов выдает случайное число с плавающей точкой от 0 до 1. Таким образом, по модулю 5 ничего не происходит, а при нарезке на массив с аргументом с плавающей запятой Ruby просто округляет его, так что это всегда возвращает Джона.


11

Perl

три srandс сделает это в три раза больше случайным!

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

объяснение

в perl нет $ RANDOM, это неопределенная переменная. код всегда будет возвращать первый элемент из списка - напитки на Джона :)

редактировать:

после прохождения кода один из пяти парней решил исправить очевидную ошибку, выпустив следующую программу:

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

Вы можете сказать, кто это сделал, просто взглянув на код?

объяснение:

в Perl $#arrayвозвращает индекс последнего элемента; так как массивы нуля, дали ссылку на массив с пятью элементами, $#$aref_peopleбудет 4.
randвозвращает случайное число, большее или равное нулю и меньшее его параметра, поэтому оно никогда не вернется 4, что фактически означает, что Джули никогда не будет покупать напитки :)


1
$RANDOMэто реальная особенность в bash, ksh и zsh (но не в perl).
— Керни

10

питон

Все знают, что вы не можете доверять случайности в таком небольшом выборочном пространстве; чтобы сделать его действительно случайным, я отказался от устаревшего метода выбора имени из списка, и вместо этого моя программа выдает совершенно случайное имя. Поскольку у большинства имен в офисе было 4 буквы, мы согласимся на это.

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)

Естественно, я сделал некоторые подготовительные работы, чтобы убедиться, что я выбрал правильное семя.


15
Заполнение генерации случайных чисел с помощью константы слишком очевидно ..
— Восстановите Монику

@BrendanLong Это определенно подняло бы брови. Люди хотели бы проверить это, чтобы убедиться, что это случайно. А когда нет, угадайте, кто покупает напитки.
— JFA

10

С

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

Прости, Джефф!

После нескольких итераций r == 1 mod 5 из-за математики. Мораль: не пишите свой собственный PRNG, если вы плохо разбираетесь в математике. :)


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

Размер вектора фактически равен 1 из-за круглых скобок, используемых в списке инициализатора. Оператор запятой отбрасывает все имена и возвращает последнее, поэтому покупателем всегда является Рой.


10

Scala

Я знаю, что мои пользователи будут настроены скептически, поэтому я включил доказательство того, что моя случайность действительно справедлива!

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
  }

}

Один пример запуска:

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

Если кому-то еще не повезет, Джон всегда будет покупать напитки.

«Доказательство» случайности основывается на том факте, что rand(1, 4) * rand(1, 4) % 5он все еще равномерно распределен между 1 и 4 включительно. Но rand(1, 5) * rand(1, 5) % 6вырожден. Существует вероятность того, что вы получите 0, что в итоге сделает конечный результат 0 независимо от остальной «случайности».


10

JavaScript (с Underscore.js )

Поскольку javascript не имеет встроенного shuffle, мы будем использовать Underscore.js

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

_.shuffle возвращает перетасованный массив, он не изменяется на месте, как Array.prototype.sort () , извините, Джон


9

JavaScript

Вторая попытка, это немного сложнее:

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

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

argumentsПеременное локально доступны для функций и представляет собой массив из всех аргументов , передаваемых в функцию. Используя простое именование и передав массив в саму функцию, вы можете подделать, что мы берем не длину массива, а длину списка аргументов (равную 1). Это может быть даже лучше выполнено, используя специальные символы или тип шрифта.


Это было не самым трудным для обнаружения. Любой, кто создал произвольную N-арную функцию в JavaScript, знает о argumentsпеременной.
— Конор О'Брайен,

8

C ++

Чтобы быть справедливым, мы должны провести много-много испытаний и выбрать того, кого выбирают чаще всего.

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

Какова стоимость 1<<31? Извини, Джон.


Ответ на ваш вопрос спойлер UB. Я не знаю, будет ли это лучше или хуже.
— NWP

@nwp Ну, конечно, но это верно везде, где int является 32-битным дополнением 2, что, похоже, имеет место даже на 64-битной (с gcc). Я не проверял на Clang, хотя.
— пушистый

Нет, это не имеет места где int это 32-но 2-е дополнение. Значение 1 << 31 не определено. Но вам повезло, что неопределенное поведение заставляет компилятор выбирать то, что он чувствует, и, поскольку он сделан для скорости, он просто решит ничего не делать, а это то, что вам нужно.
— NWP

@nwp, 1<<31 == 0x80000000несмотря ни на что, по самому определению <<, и на дополнении 32-битной 2, это так INT_MIN. Возможно, вы думаете о том, 1<<32что может или не может == 0? (Потому что на x86 1<<32обычно оценивается в 1 ...)
— пушистый

@nwp Это на самом деле определяется реализацией. Теперь, если бы мы говорили о C, то это было бы неопределенным.
— Стюарт Олсен

7

T-SQL (2008+)

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

Объяснение:

В MS SQL Server RAND()оценивается только один раз за выполнение. Каждому имени всегда присваивается один и тот же номер, оставляя первоначальный порядок. Джон первый Отстой для Джона.

Предлагаемое улучшение:

T-SQL может производить приличное качество для каждой строки случайных чисел с RAND(CHECKSUM(NEWID())).


Я думаю, что ORDER BY NEWID () будет достаточно (нет необходимости в CHECKSUM)
— Джейкоб

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()это для временных целей, os.time()это то , что должно быть использовано math.randomseedдля хорошего RNG. К сожалению, Джули всегда покупает (по крайней мере, на моем компьютере).


math.random()без аргументов также возвращает число в диапазоне [0,1). -1 за то что не уловил.
— Мниип

@mniip: действительно заслуживает! Я исправил это сейчас.
— Кайл Канос

6

Идиоматический C ++ 11

Когда речь идет о напитках, особенно важно быть в курсе последних стандартов и стилей кодирования; Это отличный пример высокоэффективного и совместимого с идиомами средства выбора имен C ++ 11.

Он высевается из системных часов и выводит начальное число вместе с именем для проверки каждый раз.

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

Попробуйте это в прямом эфире: http://ideone.com/KOet5H

Итак, это на самом деле довольно хороший код в целом; Есть много красных сельдей, которые заставляют вас слишком внимательно присмотреться к коду, чтобы заметить очевидное - что ГСЧ на самом деле никогда не засеивается :) В этом случае seedэто просто целое число, и, хотя оно выглядит так, engineоно передается в качестве параметра функция посева, это на самом деле просто игнорируется. Переменная seed на самом деле устанавливается с часов, поэтому в конце она может быть выведена вместе с именем, чтобы добавить оскорбление ране, но все равно всегда будет Стив, который покупает напитки.


1
Меня убивает, что он не использует список инициализаторов для имен. По крайней мере, вы определенно преуспели в предоставлении кода, который кажется слишком сложным. Я не могу сказать, является ли это из-за "соответствия" или всех комментариев шума: P
— vmrob


5

питон

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) дает постоянную строку; не случайное значение


6
Несколько нерелевантное примечание: если вы используете Python 3.2 или более позднюю версию, второй аргумент random.seed()должен быть 2(по умолчанию). Если вы передадите version=1, hash()строка будет использоваться в качестве начального числа вместо всей строки, и, поскольку Python случайным образом заполняет хеш-значения строк, начиная с 3.2, вы получите фактически случайное имя.
— Blacklight Shining

5

Perl

Эмме лучше не забывать свою сумочку! Работает под strictи 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.

Объяснение здесь .


Perl 5.18 немного изменил это, введя рандомизацию хеш-ключа (чтобы избежать атак сложности хеш-коллизий).
— Конрад Боровски

4

JavaScript

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

В |0результаты в 0 все время , но похоже , что это делают некоторые другие округление.


Мне это нравится. Хотя я хотел бы сделать parseInt(Math.random(0, 4))и, возможно, добавить комментарии типа - Math.randomвозвращает двойное число, поэтому сначала преобразуйте его в целое число
— Claudiu

5
Хитрость в том, что на самом деле Math.randomничего не значит для наших скудных параметров. Числа выбирает по-своему. |0правильно округлять неожиданный результат, и поэтому не является источником какого - либо обмана.
— Кин

|0Для некоторых это очевидно (для всех нас, скорее всего), но я бы поспорил, что есть много людей, которые понятия не имеют, что он делает. Это группа, на которую я рассчитывал обмануть.
— Мэтт

3
Я имею в виду @ Matt , что |0, если вы знаете , что он делает, похоже , что это округление вниз, и это будет округление вниз, так что это не обман. (И если кто-то понятия не имеет, что |0делает, то нет смысла вводить в заблуждение код; вы можете просто сказать ему все, что хотите, чтобы он поверил.) Вместо этого неожиданное поведение в вашем ответе основано на факте, который Math.random(0,4)функционально идентичен Math.random(), потому Math.randomчто не использует параметры.
— Кин

4

J

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

Бедная Джули ... Мелочи: это, возможно, был самый чистый J, который я когда-либо писал ...

Этот код на самом деле правильный, за исключением одной вещи. ?.является равномерным rng: ?.5всегда будет возвращать 4. ?5было бы правильно.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.