実際にはランダムではないランダムスクリプト


106

オフィスでのちょっとした冗談として、誰かが名前をランダムに選ぶスクリプトを望み、その人は飲み物を一杯飲むと言いました。

人々をジョン、ジェフ、エマ、スティーブ、ジュリーと呼びましょう。

一見ランダムに見えるスクリプトを作成するのは面白いと思いましたが、実際には常に出力と同じ人を指定します(選択したユーザー次第)。

1週間後の最高得票数

そして勝者は....

(現在)158票のポールR。

ここでの回答は素晴らしいものであり、まだ投稿されていない他のアイデアを他の誰かが持っている場合は、それらを追加してください、私はそれらを読むのが大好きです。



6
@AstroCB私のお気に入りのひとつ。ボビーテーブルのすぐ後ろ。
ランチャー14年

50
ランダムに選択した場合、1人も選ばないことを除けば、ひそかになりそうです。
ブレンダンロング14年

6
@AstroCBこれも素晴らしい:dilbert.com/strips/comic/2001-10-25
gilbertohasnofb

3
私は最初のページを読みました。ほとんどの回答は常にジョンを選び、2番目に高いのはジュリー、ジェフはめったに選ばれず、スティーブは1に選ばれました。物語の教訓:誰が飲み物を買うかをランダムに決めるために並んでいるとき、自分にエマと名前を付けてください。
悲惨な変数14

回答:


171

C

貴重な飲酒時間を無駄にしないために、誰ができるだけ早く購入するかを決定することが重要です。したがって、最大のパフォーマンスを得るためには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-物理的なダイスを振るよりもはるかに高速です!;)
ジュスティ14年

16
おそらくもう少しパフォーマンスを上げるために、おそらくSIMDまたはGPGPUでさらに最適化することを考えています。;-)
ポールR 14年

7
絶対に本物のライブが適用されます。それがほんのわずかな事故であることを誰も疑問に思わないでしょう。
iFreilicht

5
それは私だけなのか、それとも見つけられないほど明白なのか?
アルビンウォン14年

3
@AlvinWongすぐに気づかなかった。繰り返しますが、私はCを定期的に使用したり、BCPLから派生した他の言語を使用したりしません。
ライモイド14年

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を見つけられることを確認するために、/ dev / randomが提供するものを喜んで使用します。結局のところ、潜在的なエラーについてプログラマーに警告することは、PHPでは致命的な罪と見なされます。


25
PHPを愛するようになった-さらに良いことに、他の人を選ぶことはめったにありません。運がよけれのであればそれだけで最初は少しバイアスさだと思われる
ファルコ

142
「...プログラマーに潜在的なエラーを警告することは、PHPでは致命的な罪と見なされます。」の+1000
jsedano 14年


85

ハスケル

常に同じ名前が返される場合は透明すぎるので、次を試してください

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
それは悪魔です!
デニーズ14年

8
まだ動きを止めていないサイコロを撮影するような気分です。
Vi。

1
@Vi。それはいい例えです。幸いなことに、MVarを使用すると、画像がぼやけないことが保証されます。:)
モノセル14年

@monocellまあ、技術的には、動いているオブジェクトの写真さえも鮮明に見えます。
ghosts_in_the_code

75

Bash-最大のシンプルさ

非常に簡単な例-教科書の方法で問題を回避しましょう。良い結果を得るために、システムクロックからジェネレーターをシードすることを忘れないでください!

#!/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
\ o /平均!!! 本当に意味!!!$SECONDSftw!\ o /
イエティ14年

何があなたの場合はどうなるsourceだけで、それを実行するのではなく、この?シバンはまだ新しいシェルまたは何かをトリガーしますか?
jpmc26

1
@ jpmc26:で実行するとsource、コマンドラインで自分でコマンドを入力した場合とまったく同じです。#!/ bin / bashはコメントなので、無視されます。これは、すべてのスクリプトに当てはまります。
暴動14年

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は、あなたがそれを呼び出すオブジェクトを変更すると信じるかもしれません。


1
OrderByが仮にオブジェクトを変更したとしても、その呼び出しは実際にリストをランダムにソートしますか?.NETに不慣れな者として、私の最初の推測では、以来、ということでしたrng.Next()一度だけ呼ばれ、配列が変化しない(または唯一のソートアルゴリズムに依存して変化する)、その結果、一定の順にソートされます。
ブリリアンド14年

1
@Brilliand OrderByに渡される引数は静的な値ではなく、要素がソートされるたびに実行され、この場合、値を比較せずにランダムな値を返します。行がnames = names.OrderBy(name => rng.Next());
user3188175 14年

1
=>これは、C#のラムダ式(クロージャー)であることを示しています。
スノーボディ14年

44

パワーシェル

$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がない場合は、オブジェクトがnullでないときに返され、そうでない場合はを返し0ます。したがって、私の答えで$names.Lengthは、1と評価されrandom -maximum 1、最大値は排他的であるため、常に0を返します。


42

Q

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

Qは常に同じ値で乱数シードを初期化します。


8
したがって、基本的にはまったくランダムではありません
サムクリーマー

3
@SamCreamer質問の目的は、出力を非ランダムにすることです。しかし、これはランダムに見えるため、法案に確実に適合します
ランチャー14年

4
申し訳ありませんが、Qの乱数はそれほどランダムではありません。この質問は確かに基準を満たしています。そのように遭遇するつもりはありませんでした!
サムクリーマー14年

ええ、そのため、randを使用するたびにランダムシードを生成する独自の方法を見つける必要がありますか?サウンド...便利。
DLeh 14年

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番目の位置に0〜4のランダムな整数を配置し@indexます。配列を印刷するとき、@ indexにランダムな整数を適切に印刷しますが、配列インデックスとして使用する場合$people[@index]、@ indexはスカラーコンテキストを使用して、リストサイズの値を与えます。1ます。

大変興味深いことに、 @people[@index]適切にインデックス付けします。

興味深いことに@people[@index]、Perlのハッシュスライスで十分なので@index、リストコンテキストで評価されます。この場合、それは単一のエントリリストであり、それが正しく動作する理由です


したがって、C(++)の用語では、リストからスカラーへの暗黙的な変換が発生します。これは、インデックス作成時にスカラーが予期されるためです。
iFreilicht

@iFreilicht正しい。Perlでは、式は、表示される場所に応じて、リストまたはスカラーとして評価できます。結果として、同じ表現でも、文脈に応じて異なる意味を持ちます。@「リストコンテキスト」のリスト変数(つまり、プレフィックスを持つ変数)は、そのすべての要素として解釈されますが、「スカラーコンテキスト」では、リスト内の要素の総数に等しいスカラーです。したがって、文字列内では、リスト変数にリストコンテキストがあり、補間されて取得されPerson X is buyingます。しかし、配列のインデックスとして、それはスカラーコンテキストを取得し、1として解釈されます
アレンG

3
これに関する問題は、Perlプログラマーがを見るとmy @index = ...、彼はすぐに「WTF ?!」と不思議に思うことです。
デロバート14年

@デロバート、なぜあなたは疑問に思うだろうか?そのようなコードは非常に頻繁に表示されます... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words;など
Matthias

@Matthiasは、行が単一の値を選択して格納するためであり、スカラーの代わりに配列に格納されるためです。
デロバート14年

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

それは常にジュリーを選びます。

角括弧内に角括弧があり、コンマ演算子はその右オペランドの値を返します。
見逃すことも非常に簡単です。以前、実際のコードでは見逃していました。


これは楽しいです。最後に、そのひどい、ひどい演算子の使用。
キーン14年

5
そのコンテキストのカンマは、技術的にはセパレータではなく演算子です。ecma-international.org/ecma-262/5.1/#sec-11.14それはひどいです。コードを読みにくくしたい場合を除きます。ここで行うように。だから、称賛。
キーン14年

2
@Coryはい、同意します-関数式(例(a,b)=>(a=b[0],b))でコードゴルフに常に使用していますが。答えを明確にしました。
歯ブラシ14年

21

C#

using System;

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

秘Theは、メソッドnew Random().NextDouble()が0〜1のdoubleを返すことです。Math.Floor()この値を適用すると、常に0になります。


24
私の一見に耐えられませんでした。;)
マーティンエンダー14年

1
@TimS。そのような?:P
Knerd 14年

2
+1、はるかに良い-私はあなたが本当にしていることを知っていますが、APIにあまり詳しくない人をだますことができます。
ティムS.

1
私はこれについて知りません。シードを指定する場合は、「ランダムな」intを取得する適切な方法を使用しないでください。var random = new Random(5); var id = random.NextInt(5);
clcto 14年

2
@clcto私の意見では、これを2回含めると、誰かにダブルテイクをさせ、理由を尋ね、問題を発見する可能性が高くなります。一度インクルードし、その後不要なコードをインクルードすると、少しのリダイレクト/不手際が生じます。ボーナス:誰かがバグの1つを修正すると、別のバグが存在します。
ティムS. 14年

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


もう1つの方法は、名前をに追加AddRangeするConcatときに混乱することList<string>です。なまけたIEqualityComparerを持つHas​​hsetを持っていることに気づきましたが、それはあまりにも珍しいことです。私のクレジットでは、これを投稿したとき、シードベースの回答は(もしあれば)あまりありませんでした。
ネイサンクーパー14年

あなたは私と同じ考えを持っていたと思いますが、あなたは少し速く、見づらくしました。+1!
tsavinho 14年

7
乱数ジェネレーターをシードすることは明らかなトリックですが、ここで見事に隠しました。素敵な仕事。
TRiG 14年

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逆(辞書編集)ソートを指定するため、Steveが常に選択されます。それは無実のタイプミスと見ることができる-Rランダムソート用
最大

3
コメントを信用するのではなく、コードを注意深く読むことをお勧めします!
TecBrat 14年

16

ルビー

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

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

これはで正しく動作しますがsort_by、のsortように動作する比較関数が必要<=>です。rand()の結果は常に正であるため、Ruby実装のsortアルゴリズムが決定論的であれば、常に同等の結果が生成されます。Ruby 1.9.3は常にJulieを出力します。


12

ルビー

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

puts names[rand() % 5]

rand() 引数を指定しないと、0〜1のランダムなフロートが生成されます。したがって、モジュロ5は何も行いません。


11

Perl

3 srand秒で3倍ランダムになります!

#!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はありません。これは未定義の変数です。コードは常にリストの最初の要素を返します-Johnを飲みます:)

編集:

コードを調べた後、5人のうちの1人が明らかなエラーを修正して、次のプログラムを作成することに決めました。

#!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、最後の要素のインデックスを返します。配列はゼロベースであるため、5つの要素を持つ配列への参照が与えられると、に$#$aref_peopleなります4
randゼロ以上でそのパラメータより小さい乱数を返すので4、戻りません。事実上、ジュリーは飲み物を買わないことを意味します:)


1
$RANDOMbash、ksh、zshの実際の機能です(perlにはありません)。
カーニグ14年

10

Python

このような小さなサンプルスペースでは、ランダム性を信頼できないことは誰もが知っています。本当にランダムにするために、リストから名前を選択する古い方法を放棄し、代わりに私のプログラムは完全にランダムな名前を綴ります。オフィスのほとんどの名前には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

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

すみません、ジェフ!

数回の反復の後、数学のため、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

スカラ

ユーザーが懐疑的であることは知っているので、私のランダム性が本当に公平であるという証拠を含めました!

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にはシャッフルが組み込まれていないため、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()としてその場で変更しません、ごめんなさいJohn


9

JavaScript

第二の試み、これは少しトリッキーです:

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

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

arguments変数は、関数のためにローカルにアクセス可能で、関数に渡されるすべての引数の配列です。単純な名前付けを使用し、配列を関数自体に渡すことで、配列の長さではなく、実際には引数リストの長さ(1)を使用していると偽装できます。これは、特殊文字またはフォントタイプを使用することで、さらに適切に実行できます。


これは見つけにくいものではありませんでした。NJavaScriptで任意の-ary関数を作成した人は誰でも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 14年

@nwp確かに、しかし、intが32ビットの2の補数であることはどこでも保持されます。これは、64ビット(gccを使用)でも当てはまるようです。ただし、Clangではテストしていません。
ふわふわ14年

いいえ、intが32であるが2の補数である場所は保持されません。1 << 31の値は未定義です。幸運にも、未定義の振る舞いはコンパイラがどんな感じでも選択するようにし、スピードのために作られているので、何もしないことを決定します。
nwp 14年

@nwp 1<<31 == 0x80000000関係なく、非常に定義することによって何を、<<と32ビットの2の補数に、それはですINT_MIN。あなたは多分、そうでないかもしれ1<<32ない== 0かについて考えていますか?(x86では、1<<32通常1と評価されるため...)
ふわふわ14年

@nwp実際には実装定義です。さて、Cについて話していたらそれは未定義です。
スチュアートオルセン14年

7

T-SQL(2008以降)

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

説明:

MS SQL Serverでは、RAND()実行ごとに1回だけ評価します。すべての名前には常に同じ番号が割り当てられ、元の順序のままになります。ジョンが一番です。ジョンのために吸います。

推奨される改善:

T-SQLは、適切な品質の行ごとの乱数を生成できますRAND(CHECKSUM(NEWID()))


ORDER BY NEWID()で十分だと思います(チェックサムは不要です)
ジェイコブ14年

7

ルア

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 14年

@mniip:本当に相応しい!今修正しました。
カイルカノス14年

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

わかりましたので、これは実際には全体的にかなり良いコードです。たくさんの赤いニシンがありますので、コードをじっくり見て、RNGが実際にシードされることはありません:)この場合seedは単なる整数でありengine、パラメータとして渡されるシード関数、実際には無視されます。シード変数は実際にはクロックから設定されるため、最後に負傷にinjury辱を加えるために名前とともに出力できますが、飲み物を購入するのは常にスティーブです。


1
名前にイニシャライザリストを使用していないことは私を殺します。少なくとも、過剰に設計されたと感じられるコードを確実に提供することに成功しました。P:私はそれがあるため、ノイズのコメントの「遵守」または全てののかどうかわかりません
vmrob

6

JavaScript

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

さて、申し訳ありMath.randomませんが、パラメータを受け取らず、常に[0、1)から数値を返します。それでも、それは幸せな可変機能であり、引数について文句を言いません!


5

Python

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

str(random)は定数文字列を提供します。ランダムな値ではありません


6
多少無関係な注意:Python 3.2以降を使用している場合、2番目の引数random.seed()2(デフォルト)でなければなりません。あなたが渡すとversion=1hash()文字列の代わりに文字列全体のシードとして使用され、Pythonはランダムシード文字列のハッシュ値は3.2で起動するので、あなたが実際にランダムな名前を取得します。
ブラックライトシャイニング14年

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

|00全ての時間で結果が、それは他のいくつかの丸めをやっているように見えます。


私はそれが好きです。私はどうなるもののparseInt(Math.random(0, 4))など多分コメントを追加- Math.randomdoubleを返すので、最初の整数に変換
クラウディウ

5
トリックは、実際にMath.randomは、わずかなパラメーターについては何も気にしないということです。独自の方法で番号を選択します。これ|0は予想外の結果を正しく丸めているため、トリックの元にはなりません。
キーン14年

|0一部の人(私たち全員が最も可能性が高い)には非常に明白ですが、それが何をするのかわからない人がたくさんいると思います。それが私がだましに頼っていたグループです。
マット14年

3
@Mattつまり|0、それが何をするか知っていれば、それ切り捨てられているように見え、切り捨てられているように見えるので、それは欺de ではありません。(誰かが何かは考えていない場合は|0ありませんが、その後、欺瞞コードには使用することはありません。あなたはちょうどあなたがそれらを信じていたいものは何でもそれらを伝えることができます。)その代わりに、あなたの答えで予期しない動作が事実に基づいているMath.random(0,4)と機能的に同一ですMath.random()、なぜならMath.randomパラメータを使用しません。
キーン14年

4

J

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

かわいそうなジュリー...雑学:これは私が今まで書いた中で最もクリーンなJだったかもしれない...

このコードは実際には正しいものですが、1つだけ例外があります。?.均一なrng:?.5は常に4 ?5を返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.