用C(N)位计算A(N)/ B(N)


15

考虑三个数字序列ABC

  • A:一个基于递归关系的序列f(n) = f(n-1)+f(n-2),以开头f(1) = 3, f(2) = 4。因此,序列开始如下:3 4 7 11 18 29 47 76 ...
  • B组合数字,即不是质数(或1)的所有整数:4 6 8 9 10 12 14 15 16 ...
  • C:Pi的数字: 3 1 4 1 5 9 2 6 5 ...

给定正整数N < 50(作为函数参数或STDIN),返回小数点的十进制值,其小数点后A(N)/B(N)C(N)数字。适用四舍五入的常规规则(如果第N + 1个数字为5或更高,则四舍五入)。如果第N位数字pi为零,则应打印一个整数。科学计数法/标准格式适用于大于1000的数字。

这是代码高尔夫,所以最短的答案以字节为单位。

一些例子:

N = 1: 0.750
N = 2: 0.7
N = 3: 0.8750
N = 4: 1.2
N = 6: 2.416666667
N = 10: 11.056
N = 20: 764.8750

当然,适用标准代码高尔夫规则。

在任何现代笔记本电脑上,该功能必须在不到两分钟的时间内终止。


当您说C(n)数字时,我们是否必须包含尾随0?
Maltysen

时间限制适用于哪个输入?
丹尼斯

@丹尼斯,你是说哪个N?如果是这样,则最多N =49。还是其他?
Stewie Griffin

JavaScript的浮点精度限制为16。过去,您将开始获得不准确的结果。这个可以吗?
Downgoat

1
@vihan我的解决方案(未发布的ATM)将pi的前49位存储在字符串中。如果您对此感到担心,则结果的准确性不需要超过9位。
ETHproductions's

Answers:


9

Pyth,60 57 58字节

.[K`.Rchu,eGsGQjT7e.ftPZQ)Je/u+/*GHhyHy^TQr^T3ZZT\0+xK\.hJ

测试线束

这非常简单-计算pi,斐波纳契数列和组合,四舍五入到C(n)位,填充到C(n)位,再加上小数点位的位置。

一个): hu,eGsGQjT7

B(n): e.ftPZQ)

C(n): e/u+/*GHhyHy^TQr99ZZT

60-> 57:清除pi计算中的n = 1个特殊情况。

57-> 58:在整个输入范围内未对pi使用足够高的精度-将99次迭代增加到1000次迭代。

关于舍入的注意事项:它使用Python的“最接近偶数”舍入系统,而不是OP指定的“向无限远”系统。但是,仅当舍入点后面的数字为5000...1.25舍入为1位数时,差异才有意义。我检查了输入范围,但从未发生,因此始终返回正确的结果。


2

PowerShell,420字节(ayyyyyyyy) 378字节

param($n);[int[]]$p="03141592653589793238462643383279502884197169399375"-Split'';$a=@(0,3,4);for($i=3;$i-lt50;$i++){$a+=$a[$i-1]+$a[$i-2]};$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111";$b=@(0);for($i=4;$i-le70;$i++){if($c[$i]-eq'1'){$b+=$i}};[double]$r=$a[$n]/$b[$n];$q=$p[$n+1];$s="";(0..($q-1))|%{$s+="0"};([math]::Round($r,$q,[MidpointRounding]::AwayFromZero)).ToString("0.$s")

感谢isaacg节省了41个字节,用于计算问题如何舍入。意味着我不必包含可怕的内容[MidpointRounding]::AwayFromZero,也不需要显式转换为[double]

这个很有趣!

展开:

# Take input N
param($n)

# First digits of pi, stored as integer array
[int[]]$p="03141592653589793238462643383279502884197169399375"-Split''

# Fibonacci sequence A(N)
$a=@(0,3,4)
for($i=3;$i-lt50;$i++){
  $a+=$a[$i-1]+$a[$i-2]
}

# Zero-indexed bitmask for if the n-th integer is composite (1) or not (0)
$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111"

# Populate B(N) as an array using the $c mask
$b=@(0)
for($i=4;$i-le70;$i++){
  if($c[$i]-eq'1'){
    $b+=$i
  }
}

# Calculation Time!
$r=(a($n))/$b[$n]

# A small golf, as $p[$n+1] gets used a couple times
$q=$p[$n+1]

# Need to generate a string of zeroes for padding
$s=""
(0..($q-1))|%{$s+="0"}

# Round the number, then send it to a string so we get the necessary number of zeroes
([math]::Round($r,$q)).ToString("0.$s")

我们可以说,PowerShell中的递归很慢,因此,我们必须构建A(N)另一个方向并将其存储到数组中,然后对其进行索引。


另外,圣牛,是否满足了输出要求呢?PowerShell默认将四舍五入到a / k /一位银行家的四舍五入,这需要利用异常冗长的语言[MidpointRounding]::AwayFromZero来切换四舍五入样式。最重要的是,我们需要填充尾随零(如果有的话)。这两个要求相结合,将最后几行从20字节 [math]::Round($r,$q)变成102字节(从$s=""+$s))……哇。


很棒的描述/评论![MidpointRounding]::AwayFromZero单独使用32个字符几乎太好/坏,
难以置信

1
请参阅我关于四舍五入的注释。PowerShell默认舍入应该可以。
isaacg

1

Javascript(ES6),302个字节

一句话:未完成。

x=>{a=[0,3,4],b=[0],c='03141592653589793238462643383279502884197169399375';for(i=1;i<x;a[i+2]=a[i]+a[++i]);for(i=1,p=[];++i<70;v=p.every(x=>i%x),(v?p:b).push(i));r=''+Math.round(a[x]/b[x]*(l=Math.pow(10,c[x])))/l;if(x==33)return r;r.indexOf`.`<0&&(r+='.');while(!r[r.indexOf`.`+ +c[x]])r+='0';return r}

pi的前49位存储在字符串中,其他两个序列自动生成。这已经打了一半。我(几乎)确定可以再压缩50个字节。

适用于所有测试用例,其余应使用。大于49或小于0的任何事件均崩溃(无论如何也绝不会遇到这些情况)。我特别喜欢0的结果:

NaN.

为什么未完成?
Beta Decay 2015年

@BetaDecay我的意思是我还没有打完高尔夫球。有时间我会尽快。
ETHproductions's

1

八度, 276 236字节

首先,我认为在这些数学工具中利用无限的准确性(并重新获得一些知识)会很酷,所以我开始编写一些算法,最后最终发现该pi值不太准确,以至于我将不得不再次使用该数组。同样,没有太大的成功:

function c(A)p="3141592653589793238462643383279502884197169399375";f=ones (1,50);f(1)=3;f(2)=4;for i=3:53f(i)=f(i-1)+f(i-2);end
i=0;x=1;while i<A
x++;for j=2:x/2
if mod(x,j)==0 i++;break;end end end
printf(["%." p(A) "f\n"],f(A)/x);end

还是很可读的,不是吗?

用法

将函数复制粘贴到八度,c使用所需值的参数调用函数:

>>> c(1)
0.750
>>> c(49)
407880480.04348

优化:

  • 替代endifendfor与之相似,end其工作方式相同
  • 将变量减i一保存一个字节
  • 删除num2str(str2num(p(A)))废话:)

我喜欢您发布了一个Octave解决方案(我自己是MATLAB专家!)。请注意,此代码仅是Octave,而不是MATLAB。MATLAB使用end,而不是endif,保存了这么多字节。如果您还碰巧有MATLAB的符号工具箱,则可以使用vpapi:获得足够的小数点vpa(sym(pi),49)。我在这台笔记本电脑上没有它,所以我不确定sym那里是否有必要,但是无论如何应该节省一些字节=)而且可读性在代码golf中不一定是一件好事=)
Stewie Griffin

x ++也不是MATLAB命令。我不知道两者之间有如此大的差异……IMO,不应该如此。我认为所有用Octave编写的代码都应可移植到MATLAB(但不一定相反,因为MATLAB有更多选择)。
Stewie Griffin's

批准您的编辑。我周围没有matlab,因此无法测试。我正在寻找解决方案以在八度中获得更多pi小数,但是不幸的是,没有什么比数组短。但是ommiting whileendwhile和类似作品很好,所以我更新的答案与少一些字符:)
Jakuje
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.