将随机数映射到pi


27

十进制的双精度表示只能保证15个小数位的精度,因此pi近似为:

3.141592653589793

您可以看到数字3在位置1, 10, 16,数字1在位置2, 4等。

挑战

您的任务是创建一个程序或函数,该程序或函数将创建一个介于0和1之间的随机双数,并将该数字的值映射到pi的值。您可以通过将不同的数字放置在随机数中pi在数字中的位置来实现。如果在pi中找不到该数字,则将其跳过,并且pi中所有不在随机数中的数字都将以表示x。从左侧开始,每个值只能使用一次。

一些示例可能会更清楚地说明这一点。在以下示例中,第一个数字是pi,第二个是随机数,最后一个是所需的输出。

3.141592653589793
0.111111111111111
x.1x1xxxxxxxxxxxx

3.141592653589793
0.531000000000000
3.1xx5xxxxxxxxxxx

3.141592653589793
0.123456789123456
3.141592653x8x7xx

3.141592653589793
0.967552381459391
3.14159265358979x

规则:

  • 该函数不应接受任何输入(可能的异常在项目要点3中进行了说明)
  • 输出应仅由输出字符串组成,并带有可选的换行符(也可以接受单个尾随空格)
  • 如果您的程序没有内置的Pi值和/或RNG,则可以对Pi进行硬编码,然后将随机数作为输入。您不能对随机数进行硬编码或将Pi用作输入。
  • Pi的硬编码值和15个随机数字(可以跳过,0.因为您知道它在0到1之间)都将包括在字节数中。
  • 如果您的语言没有要求的精度,则可以在以下限制下使用较低的精度
    • Pi的数字必须精确到您所拥有的精度
    • 输出的值不能超过保证正确的值,即,如果精度只允许8个精确的小数,则不能输出15位数字。
    • 即使您的程序仅支持8位数字,Pi的硬编码值也将计为16个字节(不需要小数点)。
    • 随机数的输入值将计为15个字节(您不需要0.。这是因为精度较低的语言不应有不公平的优势。
    • 该程序必须支持5位小数精度(至少)。
    • 编辑:要验证答案:应该以某种方式打印随机数,但是此操作不必包含在字节数中。因此,例如,如果可以print r在脚本末尾插入a ,则该部分不会增加得分。
    • 如果它是另一项必要操作的一部分,则不能减去这些字节。也就是说,如果代码是print pi, r,则只能减去, r
    • 如果你要插入的部分代码中的几个地方,请包括两个版本(一个是打印出随机数,并且不带有注释,如一个:_p_oNo,需要打印的随机数_p确实xxx和_oNo不yyy。_p并且_oNo不会包含在字节数中。

以字节为单位的最短代码获胜。


排行榜

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


2
如果您使用内置随机数,它必须包含15位数字还是可以包含更多数字?还有输出随机数的要求吗?如果不是这样,它将使验证答案更加困难。
user81655

啊,这很不错!随机数可以超过15位数字。我将进行编辑,解释如何处理随机数。感谢您的评论!
Stewie Griffin

随机的“ 0到1 之间 ”是指0 < random < 1还是0 <= random <= 1
克里斯·德恩

@StewieGriffin我很困惑。这是否意味着我们可以使用pi的15位数字和16/17位的随机数?
雅库布2015年

@Jakube,说实话:我看错了这个问题,因此回答说它可能有更多数字,所以对您问题的回答是肯定的。现在返回该答案为时已晚,因为大多数答案都没有限制随机数字的数量。请限制为17。
Stewie Griffin

Answers:


5

Pyth,25个字节

 u&p?}HGH\x.-GH`.n0<`O017

在线尝试:演示测试显示随机数

说明:

 u&p?}HGH\x.-GH`.n0<`O017  
                .n0         the constant pi
               `            convert it into a string
                     O0     random number in the range [0.0, 1.0)
                    `       convert to string
                   <   17   only use the first 17 chars (zero, point and 15 digits)
 u                          for each char H in the pi-string:
    ?}HGH\x                    if H in G (the random number string) then H else "x"
   p                           print this char without newline
  &                            and
           .-GH                remove the digit H once from G
<space>                     suppress the output (u returns the unused digits in G)

14

LabVIEW,53个LabVIEW原语

我匹配字符串,然后将数字放入“空” x.xxx字符串中,然后从pi中删除该数字,以使其不再显示。

随机数和单个字符在这里是可见的,是好吗还是我必须重做录音?


即使很难看到几个字符,也可以很清楚地完成工作,因此您不必重做任何事情……不错的答案!=)
Stewie Griffin 2015年

6

Mathematica,105或147个字符

如果随机数“ 0和1 之间 ”表示0 <= random <= 1,即包括0和1。

StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,RandomInteger[{0,9},15]]->"x"]]

(105个字符)

否则,将随机数“ 0到1 之间 ”表示为0 < random < 1

循环获取15个随机整数,而不是全部为零。从0到9的范围内选择补码,即0到9的数字不在随机列表中。将这些整数转换为字符串,并替换pi字符串中的匹配字符。

(147个字符)

While[True,r=RandomInteger[{0,9},15];
If[Union@r!={0},Break[]]];
StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,r]->"x"]]

3.1x15x265358x7x3

随机数字:-

FromDigits[r]

820307536180783


做完了 仅包含换行符以提高可读性。
克里斯·德恩

2
对我来说仍然是149个字节(带换行符,不带换行符为146个字节)。同时添加高尔夫球版和非高尔夫球版都没有错。打高尔夫球的一些技巧:True1>0RandomInteger可以使用infix符号{0,9}~RandomInteger~15。您可能可以通过提供r一些值并实际使用the的条件While而不是使用Break.Then 来节省一些字节,然后For可以保存另一个字节While。尽管我不明白为什么假设范围内的随机数根本不需要循环[0,1)
马丁·恩德

@MartinBüttner我喜欢1>0:-)
Chris Degnen 2015年

我通常会读“在0和1之间的”随机数来表示0 <随机<1
克里斯Degnen

5

JavaScript(ES6),89 87字节

_=>(r=[...Math.random()+""],Math.PI+"").replace(/./g,d=>(r[i=r.indexOf(d)]=_,~i?d:"x"))

说明

编辑:随机字符串现在不被海报所说明的截断。

循环遍历pi的每个数字,并从随机数中删除该数字(如果找到),否则用替换pi中的数字x

_=>(
    r=[...Math.random()+""],      // r = array of 15 digit random number chars
    Math.PI+"").replace(/./g,d=>( // for each digit d of pi, includes "." which is always
                                  //     in the random number
      r[i=r.indexOf(d)]=_,        // i = position of d within r, remove digit from r
                                  // "_" is the unused function argument (equals undefined)
      ~i?d:"x"                    // if found, leave the digit, else replace with x
    ))

测试

测试也会输出随机数。


random()不能产生15个零,它们对应于0.000 ...或1.000 ...?即不是0和1之间
克里斯Degnen

@ChrisDegnen Math.random()会产生一定范围的范围,[0,1)因此它可以0但不会1。OP没有具体说明范围是包含范围还是排除范围,因此我认为合理的范围都可以。这也是其他答案使用的范围。但是,您已经使我意识到,如果确实0如此,它将失败,因为.in pi将不匹配而变为x。发生这种情况的几率为1分2到53,但我还是决定修复此问题。
user81655

:-)对不起。
克里斯·德恩

随机双精度命中0或1的可能性可以忽略不计,因此出于此挑战的目的,范围[0,1]也不错(也是(0,1))。
Stewie Griffin 2015年

真好 我建议一个较短的变体。
MST

3

CJam,48 46 42 38 36字节

P`'xf+1dmr`{1$f#:!1a/0=:)W+H<.%}/1f=

在这里测试。

这是同时打印π和随机数的版本:

P_p`'xf+1dmr`_oNo{1$f#:!1a/0=:)W+H<.%}/1f=

在这里测试。

正如OP在评论中所阐明的,我没有将随机数截断为15个小数位。

说明

这个想法是将π的字符串表示形式中的每个字符变成一对该字符和x。对于随机数中的每个字符,我们交换以该字符开头的第一对字符。最后,我们输出每对的第二个字符。

P`      e# Get string representation of π.
'xf+    e# Append "x" to each character.
1dmr`   e# Get string representation of random number in [0,1).
{       e# For each character in that string...
  1$    e#   Copy the list of pairs.
  f#    e#   For each pair, find the index of the current character. If the character is
        e#   not in the pair, we get -1 (truthy). If it is the first character of the pair,
        e#   we get 0 (falsy). If it is the second character, we get 1 (truthy).
  :!    e#   Logical NOT for each of the results. We get a 1 for every pair we could
        e#   potentially swap.
  1a/   e#   Split around those 1s.
  0=    e#   Keep only the first chunk.
  :)    e#   Turn all the 0s into that chunk into 1s.
  W+    e#   Append a -1.
  H<    e#   Truncate to 17 elements (the number of pairs).
  .%    e#   Apply % pairwise. This reverses the element at the position of the -1.
}/
1f=     e# Select the second character from each pair.

2

Lua 231230字节

m,s=math,""p,r=m.pi..s,s..m.random()p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(47>c:byte()and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)print(s)

说明

function f()
  m,s=math,""
  p,r=m.pi..s,s..m.random()
  p=p:sub(1,#p-1)                       -- remove the last digit of math.pi

  p:gsub(".",function(c)
    s=s..(47>c:byte()and c or"x")      -- Construct a string full of "x" with a single dot
  end)

  r:gsub("[^%.]",function(c)            -- Iterate over each character but the dot in the random number
    l=p:find(c)                         -- if c isn't in pi, l=nil 
    if l                                -- which is one of the two falsy value in lua
    then
      p,s=p:sub(1,l-1).."x"..p:sub(l+1),-- If c is in pi, we replace it in p by an x
          s:sub(1,l-1)..c..s:sub(l+1)   -- and in s by its value
    end
  end)
  return s
end

可悲的是,lua根本对我没有帮助。math.pi将pi的最后一位取整:

print(math.pi)
>> 3.1415926535898

我必须截断这个数字:

stringPI=""..math.pi
print(stringPI:sub(1,#stringPI-1))
>> 3.141592653589

进行此挑战的第二个大默认值是缺少string.replace()。当我使用两次执行此操作时s:sub(1,l-1)..c..s:sub(l+1),我想做一个匿名函数,以为会更短一些。不是,所以我写了两次。

我必须小心点的原因是lua如何返回其位置。在正则表达式中,点表示“任何字符”,因此当我评估.循环中的字符时,它与第一个字符匹配:

c="."  -- The value of the dot in the loop
found = stringPI:find(c)
print(stringPI)
print("location of \".\": "..found)
print("char at "..found..": "..stringPI:sub(found,found))

>> 3.141592653589
>> location of ".": 1   --Keep in mind that lua arrays are 1-based :)
>> char at 1: 3 

您可以在线测试lua 。由于我没有植入PRNG,因此下面的代码可以让您在观察值的同时运行多个测试。

function f()m,s=math,""p,r=m.pi..s,s..m.random()print("Random number: "..r)p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(c:byte()<47 and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)return s end

for i=1,10
do
    print(f())
end

2

Python 2.7版,117个 110字节

import math,random
n=list(`random.random()`)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)

在最新的QPython Android应用上进行了测试,但可以在任何地方使用。

编辑1:更改str(pi)为反引号。

供测试用:

import math,random
n=list(`random.random()`)
print `math.pi`
print ''.join(n)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)

好答案!的“撇号SO用来标识用代码”是反引号或树林符号,顺便:-)

1

Python,147个字节

import math as m,random as r
L=lambda t:[_ for _ in str(t)]
p=L(m.pi)
R=L(r.random())
A=""
print R #subtracted from byte count
for n in p:
    try:R.remove(n);A+=n
    except:A+='x'
print A

完全不言自明:lambda函数将float转换为list;然后,我们遍历pi列表,尝试从随机列表中删除每个数字。如果可以的话,将其添加到答案中;如果不是,请附加一个“ x”。


str(t)只能提供的11位数精度trepr(t)给您t的15位数全部精度。
Noodle9年

1

Perl,70个字节

$_=4*atan2(1,1);s/\d/x$&/g;for$i(rand=~/\d/g){s/x$i/$i/}s/x./x/g;print

有评论:

$_=4*atan2(1,1);        # Perl doesn't have a Pi constant
s/\d/x$&/g;             # prepend a x to all digits in Pi
for $i (rand=~/\d/g)    # iterate the digits in the random number
{ s/x$i/$i/ }           # replace first occurrence of x-nr pair 
s/x./x/g;               # strip all remaining numbers
print                   # print!

此版本将打印pi,随机数和结果:

$_=$p=4*atan2(1,1);
s/\d/x$&/g;
$r=rand;
for $i ($r=~/\d/g)
{ s/x$i/$i/ }
s/x./x/g;
print "$p\n$r\n$_\n"

输出示例:

3.14159265358979
0.877757977767946
x.x4x59x6xxx897x

我希望这样可以:

  • pi总共包含15个数字,其中包括3个数字,因此不会超过精度。
  • 最后一位(9)是正确的。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.