Aslında rastgele olmayan rastgele komut dosyası


106

Ofiste küçük bir şaka olarak birisi rastgele bir isim seçen bir senaryo istedi ve söylenen kişi bir tur içki yapacak.

İnsanlara John, Jeff, Emma, ​​Steve ve Julie diyelim.

Hızlı bir bakışta rastgele görünen bir senaryo yazmanın komik olacağını düşünmüştüm, ama aslında her zaman çıktıyla aynı kişiyi verir (seçtiğiniz kime kadar).

En yüksek oyu alan cevap bir hafta sonra kazanır

Ve kazanan....

Paul R (şu anda) 158 oyla.

Buradaki cevaplar çok iyi ve eğer henüz bir başkası henüz yayınlanmayan başka bir fikri varsa, lütfen onları ekleyin, onlarla okumayı seviyorum.



6
@AstroCB favorilerimden biri. Bobby masaların hemen arkasında.
Cruncher

50
Asla bir kişiyi seçmemek dışında, rastlantısal olsaydı, sinsi olurdu.
Brendan Long,


3
İlk sayfaya baktım: çoğu cevap her zaman John'u, 2. en yüksek Julie'yi, Jeff nadiren ve Steve'i 1 ile seçti. Ray bile bir kişi tarafından seçildi, ama kimse Emma'yı seçmedi. Hikayenin ahlaki: içecekleri kimin satın alacağına rastgele karar vermek için sıraya girdiğinizde, kendinize Emma adını verin.
Sefil Değişken Değişkeni

Yanıtlar:


171

C

Değerli içme zamanını boşa harcamamak için kimin mümkün olduğunca çabuk aldığına karar vermek önemlidir - bu nedenle en yüksek performansı elde etmek için C açık bir seçimdir:

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

Açıklama:

Bu break;, anahtar ifadesinde her davadan sonra olsaydı iyi sonuç verirdi . Bununla birlikte, her vaka bir diğerine “düştü” derken, fakir Julie her zaman içkileri satın alır.


17
Performans için +1 - fiziksel bir kalıba binmekten çok daha hızlı! ;)
Jwosty

16
Sadece biraz daha fazla performans elde etmek için belki de SIMD veya GPGPU ile daha da optimize etmeyi düşünüyorum. ;-)
Paul R

7
Kesinlikle gerçek canlı uygulanabilir. Hiç kimse bunun en ufak bir kaza olduğunu bile sorgulamaz.
iFreilicht

5
Sadece ben miyim yoksa bu çok açık bir şekilde görülmedi mi?
Alvin Wong,

3
@AlvinWong Hemen farketmedim. Sonra tekrar, C'yi düzenli olarak kullanmam veya BCPL'den gelen başka bir dili kullanmam.
Rhymoid

164

PHP

Bunun gitmesine izin veremezdim, işte bir tane daha:

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

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

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

Bu aslında john üretmek için garanti edilmez, ancak şans çok iyi. PHP mutlu bir şekilde / dev / random 'un alacağı şeyi alacaktır (muhtemelen) onu çözümleyemez ve bunun yerine çok makul 0 rakamı bulur. Sonuçta, programlayıcıyı olası bir hataya karşı uyarmak PHP'de ölümcül bir günah olarak kabul edilir.


25
PHP'yi sevmelisin - ve daha da iyisi, bazen nadiren başka birini seçer. Yani eğer şanslıysanız ilk başta biraz yanlı görünecek
Falco

142
+1000, "... programlayıcıyı olası bir hataya karşı uyarmak PHP'de ölümcül bir günah olarak kabul edilir."
jsedano


85

Haskell

Her zaman aynı adı döndürürse çok saydamdır, aşağıdakileri deneyin

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

Ne zaman rastgele olmasını istersen:

[~]$ runghc prog.hs
Shuffling
Steve

[~]$ runghc prog.hs
Shuffling
Julie

Ve talihsiz hedefiniz için:

[~]$ runhugs prog.hs
Shuffling
John

[~]$ runhugs prog.hs
Shuffling
John

Hugs sadece işbirlikçi çoklu görev gerçekleştirir, bu yüzden rotateiplik asla çalışmayacak


24
Bu şeytani!
Daenyth

8
Henüz hareket etmeyi bırakmayan bir zar fotoğraflamak gibi geliyor.
Vi.

1
@Vi. Bu güzel bir benzetme. Neyse ki MVars kullanımı resmin bulanık olmayacağını garanti eder. :)
monocell

@monocell Teknik olarak, hareketli bir nesnenin bir fotoğrafı bile net olabilir.
ghosts_in_the_code 27:16

75

Bash - maksimum basitlik

Çok basit bir örnek - ders kitabı yoluyla yaparak herhangi bir problemden kaçınalım. İyi bir sonuç için jeneratörü sistem saatinden çekmeyi unutmayın!

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

Bu, kullanıcının $SECONDSaslında ne yaptığını bilmemesine dayanır ; Geçerli kabuğun başlamasından bu yana saniye sayısını döndürür. Bir komut dosyasında olduğu gibi, kabuk her zaman sıfır saniye önce başladı, bu nedenle jeneratör her zaman tohumlanır 0ve Julie her zaman bira satın alır.

Bonus:

Bu, oldukça iyi bir incelemeye dayanıyor; Aynı kodu bir komut dosyası yerine komut satırına girerseniz $SECONDS, kullanıcının etkileşimli kabuğunun çalıştığı sürenin uzunluğunu döndüreceğinden rasgele sonuçlar verir .


9
\ o / Ortalama !!! Gerçekten demek !!! $SECONDSftw! \ o /
yeti

Bunu sourceyürütmek yerine, sadece yürütmek yerine ne olur ? Shebang hala yeni bir kabuk falan tetikleyecek mi?
jpmc26

1
@ jpmc26: birlikte uygularsanız, komut satırında sourcekomutları kendiniz yazdığınızdakiyle tamamen aynıdır; #! / bin / bash bir yorumdur, bu nedenle dikkate alınmaz. Bu, herhangi bir komut dosyası için geçerlidir.
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]);
        }
    }
}

Bu, .Net API'sine aşina olan insanları kandıramaz, ancak bilmeyen insanlar OrderBy, üzerinde çağırdığınız nesneyi değiştirdiğine inanıyor olabilir ve bu, yeni başlayanlar için API'ye yapması gereken makul bir hata olabilir.


1
OrderBy nesneyi varsayımsal olarak değiştirmiş olsa bile, bu çağrı listeyi rastgele sıralar mı? .NET ile aşina olmayan biri olarak, ilk tahminim rng.Next(), yalnızca bir kez çağrıldığından beri , dizinin bir sabit tarafından sıralanacağı ve hiçbir değişikliğe (veya yalnızca sıralama algoritmasına bağlı bir değişime yol açmayacağına) ilişkin oldu.
Brilliand

1
@Brilliand OrderBy'ye iletilen argüman statik bir değer değil, bir öğenin her sıralanışında yürütülür ve bu durumda herhangi bir değeri karşılaştırmadan rastgele değerler döndürür. Satır olsaydı aslında doğru çalışacaktınames = names.OrderBy(name => rng.Next());
user3188175 0

1
Bunun =>bir C # lambda ifadesi olduğunu gösterir (kapanma).
Snowbody

44

Güç kalkanı

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

Bu her zaman çıkacaktır John.

$namesBir olan System.Collections.Hashtablebir yok olan Lengthözellik. PowerShell v3 ile başlayarak, Length(ve ayrıca Count) herhangi bir nesne üzerinde özellik olarak kullanılabilir. Bir nesne özelliğe sahip değilse 1, nesne boş olmadığında geri dönecektir, aksi halde döndürecektir 0. Yani benim cevabımda, $names.Length1 olarak değerlendirir random -maximum 1ve maksimum seçkin olduğundan her zaman 0 döndürür.


42

S

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

Q her zaman rasgele sayı tohumunu aynı değerde başlatır.


8
bu yüzden temelde hiç rastgele değil
Sam Creamer

3
@ SamCreamer Sorunun amacı çıktıyı rasgele hale getirmek için çok fazla. Ama bu rastgele görünüyor, bu yüzden kesinlikle tasarıya uyuyor
Cruncher

4
Üzgünüm, demek istediğim, Q'nun rasgele sayıları o kadar rasgele değil, bu soru kesinlikle kriterleri karşılıyor. Bu şekilde rastlamak istemedim!
Sam Creamer

Evet, yani Rand'ı her kullanmak istediğinizde rastgele bir tohum üretmek için kendi yolunuzu bulmak zorundasınız. Kulağa ... kullanışlı.
DLeh

1
Rasgele tohumu elle çok kolay bir şekilde ayarlayabilir miyim ... tercümana bir -S 1234seçenekle başlayın veya \S 1234tercümandan yapın
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";

Çıktıları: Person X is buying: Jeff(X, 0-4 arasındadır)

Skaler bağlamı biraz kötüye kullanmak. @index = int(rand() * 5)0 - 4 arasında rastgele bir tamsayıyı @indexlistenin 0'a yerleştirir . Diziyi yazdırırken, rasgele tamsayıyı @index'te düzgün bir şekilde yazdırır, ancak içinde bir dizi indeksi olarak kullanıldığında $people[@index], @index, skalar bağlamı kullanır, yani liste boyutunun değerini verir 1.

İlginçtir ki, @people[@index]düzgün bir şekilde endekslenir.

İlginçtir ki @people[@index], Perl'de bir karma dilimdir, dolayısıyla @indexliste bağlamında değerlendirilir; Bu durumda, tek bir giriş listesi ve bu yüzden doğru çalışıyor


Yani C (++) terimlerinde, listeden skaler olaya doğru örtük bir dönüşüm var çünkü indeksleme sırasında skaler bekleniyor?
iFreilicht

@ iFreilicht Doğru. Perl'de ifadeler, göründükleri yere göre liste veya skaler olarak değerlendirilebilir. Sonuç olarak, aynı ifade bağlama bağlı olarak farklı anlamlara gelebilir. @"List bağlamında" bir liste değişkeni (yani öneki olan bir değişken ) tüm öğeleri olarak yorumlanır, ancak "skaler bağlamda", listedeki toplam öğe sayısına eşit bir skalardır. Bu nedenle, dizgenin içinde liste değişkeni liste içeriğine sahiptir ve enterpolasyon yapar ve elde ederiz Person X is buying. Fakat bir dizi indeksi olarak, skaler bağlam alır ve 1 olarak yorumlanır.
Allen G

3
Bununla ilgili sorun, bir Perl programcısı göründüğünde my @index = ...hemen "WTF ?!" diye merak etmesidir.
derobert

@derobert, neden merak ediyorsun? Sık sık böyle kod görüyorsun ... my @letters = 'a' .. 'z'; my @squares = map $_**2, 1..20; my @sorted = sort { lc $a cmp lc $b } @words;vb.
Matthias

@Matthias, çünkü satır tek bir değer seçmek ve depolamaktır ve bir skaler yerine bir dizide saklanmaktadır.
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]);

Her zaman Julie'yi seçer.

Köşeli parantez içinde parantez vardır ve virgül operatörü sağ işlenenin değerini döndürür.
Ayrıca kaçırması çok kolay. Daha önce gerçek kodda özledim .


Bu çok hoş. Sonunda, bu korkunç, korkunç operatör için bir kullanım.
Keen

5
Bu bağlamdaki virgül, teknik olarak bir ayırıcı yerine bir işleçtir. ecma-international.org/ecma-262/5.1/#sec-11.14 Ve korkunç. Kodunuzun okunması zor olmadıkça. Burada yaptığınız gibi. Peki, kudos.
Keen

2
@Cory Evet, katılıyorum - her zaman kod ifadeleri için işlev ifadeleriyle kullanıyorum (örn. (a,b)=>(a=b[0],b)). Cevabımı netleştirdim.
Diş fırçası,

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

İşin püf noktası, yöntem new Random().NextDouble()0 ile 1 arasında bir ikiye katlanır Math.Floor(). Bu değere uygulandığında , her zaman 0 olur.


24
Benim hızlı bakışa dayanamadı. ;)
Martin Ender

1
@TimS. bunun gibi? : P
Knerd

2
+1, Çok daha iyi - Gerçekten ne yaptığınızı biliyorum, ancak API'ye aşina olmayan birini kandırabilir.
Tim S.,

1
Bunu bilmiyorum. Eğer bir tohum belirtecekseniz, neden sadece "rasgele" bir int almanın doğru yolunu kullanmıyorsunuz:var random = new Random(5); var id = random.NextInt(5);
clcto

2
@ clcto Kanımca, iki kez dahil olmak üzere, birinin iki katına çıkması, nedenini sorması ve sorunu görmesi daha olasıdır. Bir kez eklenmesi ve daha sonra gereksiz kodların eklenmesi, bir miktar yeniden yönlendirme / önemsizlik verir. Bonus: Birisi böceklerden birini düzeltirse, bir başkası vardır.
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]);

İpucu:

GUID'den tohum üret. Kılavuzların 4 × 10−10 çarpışma şansı var. Süper rastgele.

Cevap:

En azından ne zaman kullanıyorsun Guid.NewGuid(), boğmaca! (Her zaman 0 tohum yapmak için sinsi yolu). Ayrıca yanlış yönlendirme için anlamsız (int).


Bunu AddRangeyapmamın bir başka yolu da, a'ya Concatisim eklerken karışması List<string>. Sinsi bir IEqualityComparer ile bir Hashset olması bana meydana geldi, ama sadece çok sıradışı olurdu. Kredimde, bunu gönderdiğimde çok (varsa) tohum temelli cevap yoktu.
Nathan Cooper,

Sanırım benim de benim yaptığımla aynı fikre sahipsin, ama biraz daha hızlıydın ve görmesini biraz zorlaştırdın. 1!
tsavinho

7
Rasgele sayı üretecini tohumlamak açık bir numaradır, ancak onu zekice buraya gizlediniz. Güzel iş.
TRiG

18

bash / coreutils

Bu neredeyse benzer bir amaç için yazdığım bir senaryodan yazılı olarak alınmıştır.

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

Büyük harf kullanmayı unutmayı bile R, zaman zaman gerçek hayattaki senaryolarda yaptığım bir hatadır.


3
daha iyi bir açıklama yapabilir misin? Şu anki durumunuz çok kısa ve bash ile aşina olmayan birine yardımcı değil.
iFreilicht

6
-rreverse (lexicographic) sıralamasını belirtir, böylece Steve her zaman seçilecektir. Bu -Rrastgele sıralama için masum bir yazım hatası olarak görülebilir
Max

3
Bu, yorumlara güvenmemek, ancak kodu dikkatlice okumak için iyi bir hatırlatmadır!
TecBrat

16

Yakut

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

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

Bu, doğru şekilde çalışır sort_by, ancak sortbunun gibi çalışan bir karşılaştırma işlevi bekler <=>. rand () 'ın sonucu her zaman pozitif olacaktır, bu nedenle Ruby uygulamanızın sortalgoritmasının deterministik olması şartıyla her zaman eşdeğer sonuçlar üretecektir . Benim Ruby 1.9.3 her zaman Julie'nin çıktısını alır.


12

Yakut

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

puts names[rand() % 5]

rand() hiçbir argüman olmadan 0 ile 1 arasında rasgele bir float üretir. Böylece modulo 5 hiçbir şey yapmaz ve bir float argümanına sahip bir diziye dilimleme yapılırken Ruby sadece onu yuvarlar, bu yüzden bu her zaman John'a döner.


11

Perl

üç srands üç kat daha rastgele yapacaktır!

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

açıklama

perl'de $ RANDOM yoktur, tanımsız bir değişkendir. Kod her zaman listedeki ilk elemanı döndürür - John’daki içecekler :)

Düzenle:

Kodun üzerinden geçtikten sonra, beş kişiden biri, aşağıdaki hatayı üreten bariz hatayı düzeltmeye karar verdi:

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

Sadece koda bakarak kimin yaptığını söyleyebilir misin?

açıklama:

Perl'de $#arrayson elemanın dizinini döndürür; diziler sıfır tabanlı olduğundan, beş öğeli bir diziye referans verildiğinde, $#$aref_peopleolacaktır 4.
randparametresinden sıfıra eşit veya daha küçük veya daha büyük bir rasgele sayı döndürür, böylece hiçbir zaman geri dönmez 4, bu da Julie'nin asla içecek almayacağı anlamına gelir.


1
$RANDOMbash, ksh ve zsh'daki (ancak perl'de değil) gerçek bir özelliktir.
kernigh

10

piton

Herkes bu kadar küçük bir örnek alanda rastgeleliğe güvenemeyeceğinizi bilir; Gerçekten rastgele yapmak için listeden bir isim seçmenin modası geçmiş yöntemini bıraktım ve bunun yerine programım tamamen rastgele bir isim yapacak. Ofisteki isimlerin çoğunun 4 harfi olduğundan, bunun için karar vereceğiz.

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)

Doğal olarak, doğru tohumu seçtiğimden emin olmak için bazı hazırlık çalışmaları yaptım.


15
Bir sabittir ile rastgele sayı üretmek Tohum çok açıktır ..
Brendan Long

@BrendanLong Kesinlikle kaşları kaldırır. İnsanlar rastgele olduğundan emin olmak için test etmek ister. Olmadığında, tahmin et kimin içecek aldığını.
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] );
}

Üzgünüm Jeff!

Birkaç yinelemeden sonra r == 1 mod 5, matematikten dolayı. Ahlak: Eğer matematikte kötüyseniz kendi PRNG'nizi yazmayın. :)


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

Başlatıcı listesinde kullanılan parantez nedeniyle vektörün boyutu aslında 1'dir. Comma operatörü tüm isimleri atacak ve sonuncuyu geri döndürecek, bu nedenle alıcı her zaman Roy.


10

Scala

Kullanıcılarımın şüpheci olacağını biliyorum, bu yüzden rastlantısallığımın gerçekten adil olduğunu kanıtladım!

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
  }

}

Bir örnek çalıştırma:

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

Başkası çok şanslı olmadığı sürece, John içkileri daima satın alır.

Rasgeleliğin "kanıtı" rand(1, 4) * rand(1, 4) % 5, hala dahil olmak üzere hala 1 ile 4 arasında eşit dağılmış olmasına dayanır . Fakat rand(1, 5) * rand(1, 5) % 6yozlaşmış. 0 alma olasılığı vardır, bu da "rastgele" nin geri kalanından bağımsız olarak nihai sonucu 0 yapar.



9

JavaScript

İkincisi, bu biraz daha zor:

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

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

argumentsDeğişken işlevleri için lokal olarak erişilebilir ve işleve geçirilen tüm bağımsız değişkenler bir dizidir. Basit isimlendirmeyi kullanarak ve bir diziyi fonksiyonun kendisine geçirerek, dizinin uzunluğunu değil, gerçekte argümanlar listesinin uzunluğunu (1 olan) aldığımızı taklit edebilirsiniz. Bu, özel karakterler veya yazı tipi kullanılarak daha da iyi gerçekleştirilebilir.


Bu tespit edilmesi zor değildi. NJavaScript'te isteğe bağlı bir işlev oluşturmuş olan herkes argumentsdeğişken hakkında bilgi sahibi olur .
Conor O'Brien,

8

C ++

Adil olmak gerekirse, pek çok deneme yapmalı ve en çok kimin seçildiğini seçmeliyiz.

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

Değeri nedir 1<<31? Üzgünüm John.


Spoyler sorunuzun cevabı UB. Bu daha iyi ya da daha kötü yaparsa kararsızım.
nwp

@nwp Pekala, elbette, ama int'nin 32-bit 2'nin tamamlayıcısı olduğu her yerde tutuyor, ki bu 64-bit'de bile görünüyor (gcc ile). Yine de Clang'da test etmedim.
kabarık

Hayır, int'nin 32 ama 2'nin tamamlayıcısı olduğu hiçbir yerde tutmaz. 1 << 31'in değeri tanımsız. Yine de şanslısınız, tanımsız davranış, derleyicinin ne hissettiğini seçmesini sağlar ve hız için yapıldığı için istediğin gibi olan hiçbir şey yapmaya karar verir.
nwp

@ nwp 1<<31 == 0x80000000, tanımı gereği <<, 32-bit 2'nin tamamlayıcısı ne olursa olsun , işte bu INT_MIN. Belki 1<<32hangisinin olup olmayacağını == 0mı düşünüyorsun ? (Çünkü x86'da, 1<<32genellikle 1 olarak değerlendirilir ...)
kabarık

@nwp Aslında uygulama tanımlı. Biz C bahsediyorduk Şimdi, eğer o tanımsız olacaktır.
Stuart Olsen

7

T-SQL (2008+)

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

Açıklama:

MS SQL Server'da, RAND()yürütme başına yalnızca bir kez değerlendirir. Her isme her zaman aynı numara verilir ve orijinal sıralamayı bırakır. John ilk. John için berbat.

Önerilen gelişme:

T-SQL iyi kalitede, sıra başına rastgele sayılarla üretebilir RAND(CHECKSUM(NEWID())).


Ben SİPARİŞ NEWID () yeterli olacağını (CHECKSUM gerek yok)
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()zamanlama amaçlıdır, iyi RNG için os.time()kullanılması gereken şeydir math.randomseed. Ne yazık ki, Julie her zaman satın alır (en azından bilgisayarımda).


math.random()argüman olmadan da aralıkta bir sayı döndürür [0,1). Onu yakalayamadığım için -1.
mniip

@mniip: Gerçekten de haketti! Şimdi tamir ettim.
Kyle Kanos,

6

Deyimsel C ++ 11

İçecekler söz konusu olduğunda, en son standartlara ve kodlama stillerine ayak uydurmak özellikle önemlidir; bu, oldukça verimli ve deyim uyumlu bir C ++ 11 isim seçicinin harika bir örneğidir.

Sistem saatinden tohumlanır ve her seferinde doğrulama için adı ile birlikte tohum çıkarır.

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

Bunu canlı dene: http://ideone.com/KOet5H

Tamam, bu aslında genel olarak oldukça iyi bir kod; bariz olduğunu farketmek için çok yakından bakmak için kırmızı ringa balığı vardır - RNG'nin aslında hiç ekilmediğini gösterir :) Bu durumda seedsadece bir tamsayıdır ve görünüşe göre enginebir parametre olarak geçirilir. tohumlama fonksiyonu, aslında sadece göz ardı edilir. Tohum değişkeni gerçekten zamandan ayarlanır, bu yüzden en sonunda yaralanmaya hakaret eklemek için adla birlikte çıkarılabilir, ancak yine de içecekleri alan Steve yine de olacaktır.


1
İsimler için bir başlatıcı listesi kullanmadığı beni öldürüyor. En azından kesinlikle çok fazla kendini geliştiren hissettiren bir kod vermeyi başardın . Bunun "uyumluluk" yüzünden mi yoksa gürültü yorumlarının hepsinde mi olduğunu söyleyemem: P
vmrob

6

JavaScript

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

Üzgünüm, Math.randombir parametre almaz ve her zaman [0, 1) 'den bir sayı döndürür. Yine de, mutlu bir değişken işlevdir ve tartışmalardan şikayet etmez!


5

piton

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) sabit bir dize verir; rastgele bir değer değil


6
Biraz alakasız bir not: Python 3.2 veya daha yenisini kullanıyorsanız, random.seed()olması gereken ikinci argüman 2(varsayılan) olmalıdır. Geçerseniz version=1, hash()dizgenin tamamı dizenin tamamı yerine bir tohum olarak kullanılacaktır ve Python rastgele dizgilerin 3.2'de başlayan karma değerlerini topladığından, rastgele bir isim elde edersiniz.
Blacklight Shining

5

Perl

Emma çantasını unutmadı! Altında çalışır strictve 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.

Burada açıklama .


Perl 5.18, karma anahtar randomizasyonunu tanıtarak bunu biraz değiştirdi (karma çarpışma karmaşıklığı saldırılarını önlemek için).
Konrad Borowski

4

JavaScript

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

Her |0zaman 0 sonuçları var ama sanki başka bir yuvarlama yapıyor gibi görünüyor.


Bunu sevdim. Her ne kadar yaparsam parseInt(Math.random(0, 4))ve belki de yorumlar eklesem de - Math.randombir çift döndürür, bu yüzden önce bir tamsayıya dönüştürün
Claudiu

5
İşin püf noktası aslında Math.randomyetersiz parametrelerimiz için hiçbir şey umurunda değil. Sayıları kendi yöntemiyle seçer. |0doğru çok beklenmedik bir sonuç yuvarlama ve herhangi bir hile bir kaynağı değildir.
Keen

|0Bazılarına çok açık (hepimiz büyük olasılıkla), ama iddiaya girerim ne yaptığı hakkında hiçbir fikri olmayan çok şey vardır. Bu kandırmaya güvendiğim grup.
Matt

3
@Matt Bunu demek |0ne yaptığını biliyorsanız, aşağı yuvarlama, ve bunun gibi görünüyor edilir aşağı yuvarlama, bu yüzden bir aldatma değil. (Birisi hakkında hiçbir fikri varsa Ve |0yapar, o aldatıcı kodu için bir anlamı yoktur;. Sadece bunları inanmak istiyorlarsa onu söyleyebilirim) Bunun yerine, cevap beklenmeyen davranış gerçeğine dayanmaktadır Math.random(0,4)işlevsel aynıdır Math.random(), çünkü Math.randomparametreleri kullanmaz.
Keen

4

J

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

Zavallı Julie ... Trivia: Bu yazdığım en temiz J olabilirdi ...

Bu kod aslında bir şey dışında doğrudur. ?.tek tip rng: ?.5her zaman geri döner 4. ?5doğru olurdu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.