在办公室里有个小玩笑,有人想要一个脚本,随意选择一个名字,然后说这个人会喝一杯。
我们称他们为约翰,杰夫,艾玛,史蒂夫和朱莉。
我认为制作一个看上去一眼便是随机的脚本却很有趣,但实际上却总是将输出作为同一个人(取决于您选择的人)。
一周后投票得票率最高
最终获胜者是....
保罗·R(目前)158票。
这里的答案很好,如果其他人有其他想法尚未发布,请添加它们,我喜欢阅读它们。
在办公室里有个小玩笑,有人想要一个脚本,随意选择一个名字,然后说这个人会喝一杯。
我们称他们为约翰,杰夫,艾玛,史蒂夫和朱莉。
我认为制作一个看上去一眼便是随机的脚本却很有趣,但实际上却总是将输出作为同一个人(取决于您选择的人)。
一周后投票得票率最高
最终获胜者是....
保罗·R(目前)158票。
这里的答案很好,如果其他人有其他想法尚未发布,请添加它们,我喜欢阅读它们。
Answers:
重要的是要尽快决定谁来购买,以免浪费宝贵的饮酒时间-因此,为了获得最佳性能,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语句中的每种情况之后都有一个,这将很好地工作。但就目前情况而言,每种情况都“落到”下一种情况,所以可怜的朱莉总是以买酒为最终。
无法放手,所以这是另一个:
$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中警告程序员潜在的错误被认为是致命的罪过。
如果它总是返回相同的名称,则太透明了,请尝试以下操作
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
拥抱仅实现协作式多任务处理,因此
rotate
线程将永远不会运行
一个非常简单的示例-让我们通过教科书的方式来避免任何问题。不要忘记从系统时钟中为生成器播种,以获得良好的结果!
#!/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
内置函数的实际作用。它返回自当前shell启动以来的秒数。正如在脚本中一样,shell总是在零秒之前启动,因此生成器总是带有种子,0
并且Julie总是购买啤酒。
奖金:
这个人经得起严格的审查。如果在命令行而不是在脚本中输入相同的代码,它将给出随机结果,因为
$SECONDS
它将返回用户的交互式外壳程序运行的时间长度。
$SECONDS
tw!\ o /
source
执行此操作,而不仅仅是执行操作,会发生什么?shebang还会触发新的外壳或其他东西吗?
source
您自己在命令行上键入命令的方式完全相同;#!/ bin / bash是注释,因此将被忽略。任何脚本都是如此。
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的新手来说是一个合理的错误。
rng.Next()
仅被调用一次,因此该数组将按常量排序,而不会导致更改(或仅依赖于排序算法的更改)。
names = names.OrderBy(name => rng.Next());
=>
指示,这是一个C#lambda表达式(闭合)。
$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,因为最大值是互斥的。
show rand `John`Jeff`Emma`Steve`Julie;
exit 0;
Q总是用相同的值初始化其随机数种子。
-S 1234
选项启动解释器,或\S 1234
从解释器中进行操作
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)
在@index
列表的第0个位置放置一个0-4的随机整数。打印数组时,它会正确打印@index中的随机整数,但是当用作数组中的索引时$people[@index]
,@index使用标量上下文,并为其指定列表大小的值,即1
。有趣的是,
@people[@index]
使其正确索引。有趣的
@people[@index]
是,Perl中有一个哈希片,因此@index
在列表上下文中对其进行了评估。在这种情况下,它是一个条目列表,这就是为什么它可以正常工作的原因
@
在“列表上下文”中,列表变量(即带有前缀的变量)被解释为其所有元素,但在“标量上下文”中,它是等于列表中元素总数的标量。因此,在字符串中,list变量具有list上下文并被插值,我们得到Person X is buying
。但作为一个数组索引,它得到标量上下文,并得到解释为1
my @index = ...
,他立即想知道“ WTF ?!”。
my @letters = 'a' .. 'z';
my @squares = map $_**2, 1..20;
my @sorted = sort { lc $a cmp lc $b } @words;
等等
// Randomly pick a person on only one line!
var people = [('John', 'Jeff', 'Emma', 'Steve', 'Julie')];
console.log(people[new Date() % people.length | 0]);
它总是选择朱莉。
它在方括号内有括号,并且逗号运算符返回其右操作数的值。
也很容易错过。我以前在实际代码中已经错过了它。
(a,b)=>(a=b[0],b)
)的Code Golf中使用它。我已经澄清了答案。
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。
var random = new Random(5); var id = random.NextInt(5);
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>
。我确实有一个带有偷偷摸摸的IEqualityComparer的哈希集,但这太不寻常了。以我的功劳,当我发布这篇文章时,基于种子的答案并不多。
这几乎是我为类似目的编写的脚本的逐字记录。
#!/bin/bash
# Sort names in random order and print the first
printf '%s\n' John Jeff Emma Steve Julie | sort -r | head -1
甚至忘记使用大写字母R也是我在现实生活脚本中偶尔犯的一个错误。
-r
指定反向(字典式)排序,因此将始终选择Steve。可以将其视为-R
随机排序的纯真错字
3 srand
s将使其随机性提高三倍!
#!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上喝酒:)
编辑:
阅读完代码后,五个家伙之一决定修复明显的错误,并生成以下程序:
#!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
,这实际上意味着朱莉将永远不会购买饮料:)
$RANDOM
在bash,ksh和zsh中是一个真正的功能(但在perl中不是)。
大家都知道,在如此小的样本空间中,您不能相信随机性。为了使它真正随机,我放弃了从列表中选择名称的过时方法,而我的程序将拼出一个完全随机的名称。由于办公室中的大多数名字都有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)
自然,我做了一些准备工作以确保选择正确的种子。
#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。:)
我知道我的用户会持怀疑态度,所以我提供了一个证明我的随机性确实很公平的证明!
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之间(含1和4)。但是rand(1, 5) * rand(1, 5) % 6
退化。您有可能得到0,这将使最终结果为0,而与其余“随机性”无关。
由于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(),对不起约翰
再试一次,这有点棘手:
var getRandomEntry = function(args){
return args[Math.floor(Math.random() * arguments.length)];
}
alert(getRandomEntry(["peter","julie","samantha","eddie","mark"]));
该
arguments
变量可从本地访问函数,并且是传递给函数的所有参数的数组。通过使用简单的命名并将数组传递给函数本身,您可以欺骗我们不是在获取数组的长度,而是实际上是参数列表的长度(为1)。通过使用特殊字符或字体类型,可以更好地执行此操作。
N
在JavaScript中构造了任意-ary函数的人都知道该arguments
变量。
公平地说,我们应该进行很多次试验,并选择最常被选的人。
#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
?抱歉,约翰。
1<<31 == 0x80000000
无论如何,按照的定义<<
,在32位2的补码中,即为INT_MIN
。您是否正在考虑1<<32
可能会或可能不会== 0
?(因为在x86上,1<<32
通常求值为1 ...)
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()))
。
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表示不赶上。
当涉及饮料时,了解最新的标准和编码样式尤为重要。这是一个高效且符合习语的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
不到明显的事实-RNG实际上从未播种过:)在这种情况下,它只是一个整数,尽管它看起来像是engine
作为参数传递给种子函数,实际上只是被忽略了。种子变量实际上是从时钟开始设置的,因此可以在末尾随名称一起输出,以增加对侮辱的伤害,但是购买饮料的始终还是史蒂夫。
console.log(["Jeff", "Emma", "Steve", "Julie"][Math.floor(Math.random(5))]);
好吧,很抱歉,
Math.random
它没有参数,并且总是返回[0,1)中的数字。尽管如此,它还是一个快乐的可变参数函数,并且不会抱怨参数!
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)给出一个常量字符串;不是随机值
random.seed()
必须为2
(默认值)。如果通过version=1
,则hash()
字符串的代替整个字符串将用作种子,并且由于Python从3.2开始随机地为字符串的哈希值提供种子,因此您将获得一个实际随机的名称。
艾玛最好不要忘记她的钱包!在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.
在这里解释。
的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
返回双
Math.random
对我们微薄的参数无关紧要。它以自己的方式选择数字。的|0
正确的舍入结果意外,因此是不属于任何欺骗的源极。
|0
对某些人(最有可能是我们所有人)非常明显,但是我敢打赌,有很多人不知道它的作用。那就是我所依赖的团体。
|0
,如果您知道它的作用,那么它似乎在四舍五入,并且在四舍五入,因此这不是欺骗。(如果某人不知道该怎么|0
做,那么欺骗性代码就没有用;您可以告诉他们您希望他们相信的任何东西。)相反,答案中的意外行为是基于Math.random(0,4)
与Math.random()
,因为Math.random
不使用参数。
;(?.5) { 'John'; 'Jeff'; 'Emma'; 'Steve'; 'Julie'
可怜的朱莉...琐事:这可能是我写过的最干净的J ...
这段代码实际上是正确的,除了一件事。
?.
是统一的rng:?.5
始终会返回4.?5
正确。