整数的黄金度


21

正整数n可以表示为具有整数边 ab矩形,这样n = a * b。即,区域代表数字。通常,对于给定的nab不是唯一的。

众所周知,当矩形的边成黄金比例时φ((sqrt(5)+1)/ 2≈1.6180339887 ...

结合这两个事实,此挑战的目的是将整数n分解为两个整数ab的乘积,两个整数的比率尽可能接近φ(通常的度量标准为ℝ)。φ不合理这一事实意味着存在唯一的解对(ab)。

挑战

给定正整数n,输出正整数ab,使 a * b = na / bφ之间的绝对差最小。

例如,考虑n =12。满足a * b = n的对(ab)为:(1,12),(2,6),(3,4),(4,3),( 6,2),(12,1)。比率最接近φ的那对是(4,3),得出4/3 = 1.333。

规则

可以接受功能或程序。

分子)应出现第一输出,和分母b第二。除此之外,输入和输出格式像往常一样灵活。例如,两个数字可以作为带有任何合理分隔符的字符串或数组输出。

该代码在理论上应适用于任意大数。实际上,它可能受到内存或数据类型限制的限制。

只要考虑到φ的近似版本就足够了,只要它精确到第三个小数或更小。即,真实φ与近似值之间的绝对差不应超过0.0005。例如,可接受1.618。

当使用φ的近似,有理形式时,解决方案不是唯一的可能性很小。在这种情况下,您可以输出满足最小化标准的任意对ab

最短的代码胜出。

测试用例

1        ->  1    1
2        ->  2    1 
4        ->  2    2
12       ->  4    3
42       ->  7    6
576      ->  32   18
1234     ->  2    617
10000    ->  125  80
199999   ->  1    199999
9699690  ->  3990 2431

当然,除非您接受例如a / bb / a结果尽可能接近1 的答案,否则大多数答案肯定会使用某种近似于φ的有理近似值。
尼尔

@Neil我不确定我是否理解您的评论。您的最小化想法|a/b-b/a-1|很有希望,尽管有一个适当的证明
Luis Mendo

不确定是否可以将整个证明填入注释中,但其轮廓如下:整个矩形表示a/b。删除单位正方形后,右边的小矩形代表b/a。因此,一个黄金矩形实现为1的差
尼尔

如果a和b在斐波纳契数列中不是相邻的数字,那么在测试中是否有包含它们的点?
草莓

就是说,1618 x 1000似乎是一个不错的候选者(或者,参考而言是809 x 500)
草莓

Answers:


6

果冻,16 15 14字节

感谢@miles,节省了1个字节。

÷/ạØp
ÆDżṚ$ÇÞḢ

在线尝试!

说明

÷/ạØp         Helper link, calculates abs(a/b - phi). Argument: [a, b]
÷/            Reduce by division to calculate a/b.
  ạØp         Calculate abs(a/b - phi).

ÆDżṚ$ÇÞḢ      Main link. Argument: n
ÆD            Get divisors of n.
  żṚ$         Pair the items of the list with those of its reverse. The reversed
              divisors of a number is the same list as the number divided by each
              of the divisors.
     ÇÞ       Sort by the output of the helper link of each pair.
       Ḣ      Get the first element [a, b] and implicitly print.

您可以通过将除数列表的倒数与其自身交织来节省字节。使用÷/ạØp¶ÆDżṚ$ÇÞḢ14个字节,它返回作为参数[a, b]给出的列表n
2016年

@miles酷!我显然完全错过了/。(这是我在Pyth解决方案中所做的事情。)当我上笔记本电脑时将进行编辑。
PurkkaKoodari


6

Matlab,96 81字节

高尔夫球(-15字节),路易斯·门多的道具

function w(n);a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]

原版的:

function w(n)
a=find(not(mod(n,1:n)));b=abs(a./(n./a)-1.618);c=find(not(b-min(b)));[a(c) n/a(c)]

到目前为止,这不是一个很好的解决方案,但是我第一次尝试使用代码高尔夫球。真有趣!


2
同意这很有趣!欢迎光临本站!
DJMcMayhem

1
您可以替换not通过~ 节约几个字节。此外,使用第二个输出min可以消除finda=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo

很好发现-刮掉了很多符号!
ptev

1
您可以使用n=input('');而不是来缩短它的长度,而function w(n);()周围有多余的一对mod
瑕疵的2016年


5

Mathematica,51个字节

#&@@SortBy[{x=Divisors@#,#/x},Abs[#/#2-1.618]&]&

是Mathematica的换位后缀运算符(显示为一个标T在数学)。

Mathematica具有内置功能GoldenRatio,但是1.618短很多,尤其是因为前者也需要N@


5

Pyth,21 20 18字节

hoacFN.n3C_Bf!%QTS

在线尝试。 测试套件。

说明

  1. 获得S从1到输入的包含范围。
  2. f过滤输入的数字!%QT
  3. 得到[that list, that list reversed] _B。数字的反向除数与数字除以每个除数的列表相同。
  4. 转置列表以获取对[numerator, denominator]
  5. 小号o由室温的对a的对比率的bsolute差cFN与黄金比例.n3
  6. 获取第一对(最低)h并打印。

5

Javascript(ES6),73个字节

n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

我们寻找:

  • a = n的最大除数,其中n /φ>a²
  • b = n /φ<b²的n的最小除数

然后,解为[a,n / a][b,n / b]。我们将n /φ-a²b²-n /φ进行比较,以找出哪个表达式最接近零。

代码中使用的实际公式基于φ/ 2,可以用比φ更短的方式编写,且具有相同的精度:.809vs 1.618

因此:

n /φ >a²⇔n /(φ/ 2)>2a²

和:

n /φ-a²>b²-n /φ⇔2n /φ-a²>b²⇔n /(φ/ 2)-a²>b²

复杂

迭代次数在很大程度上取决于n个因子。最坏的情况发生在n为质数时,因为我们必须执行从1到n的所有迭代才能找到其仅2个除数。这就是199999的情况。另一方面,9699690是19平滑的,我们很快在断点√(n /φ)≈2448的两侧发现了两个除数。

测试用例

let f =
n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

console.log(JSON.stringify(f(12)));       // [ 3, 4 ]
console.log(JSON.stringify(f(42)));       // [ 6, 7 ]
console.log(JSON.stringify(f(576)));      // [ 18, 32 ]
console.log(JSON.stringify(f(1234)));     // [ 2, 617 ]
console.log(JSON.stringify(f(10000)));    // [ 80, 125 ]
console.log(JSON.stringify(f(199999)));   // [ 1, 199999 ]
console.log(JSON.stringify(f(9699690)));  // [ 2431, 3990 ]


4

JavaScript(ES6),83个字节

f=
n=>{p=r=>Math.abs(r/n-n/r-1);for(r=i=n;--i;)r=n%i||p(i*i)>p(r*r)?r:i;return[r,n/r]}
;
<input type=number min=1 oninput=[a.value,b.value]=f(+this.value)><input readonly id=a><input readonly id=b>

实际上返回(ab)对,这使a / b - b / a -1 的绝对值最小,但这至少适用于所有测试用例,尽管我想我可以使用1.618测试节省4个字节。


3

Brachylog,41个字节

:1fL:2a:Lzoht
,A:B#>.*?!,.=
:3a/:$A-$|
//

在线尝试!

说明

  • 主要谓词:

    :1fL           L is the list of all couples [A:B] such that A*B = Input (see Pred. 1)
        :2a        Compute the distance between all As/Bs and φ (see Pred. 2)
           :Lz     Zip those distances to L
              o    Sort the zip on the distances
               ht  Take the couple [A:B] of the first element of the sorted list
    
  • 谓词1:输出是一对[A:B],使得A*B = Input

    ,A:B           The list [A:B]
        #>         Both A and B are strictly positive
          .        Output = [A:B]
           *?      A*B = Input
             !,    Discard other choice points
               .=  Assign a value to A and B that satisfy the constraints
    
  • 谓词2:计算和之间的距离A/B

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • 谓词3:通过反转int将其转换为float

    /              1/Input
     /             Output = 1/(1/Input)
    

出于好奇:φBrachylog中是否预定义了文字?还是在代码中定义了它?
路易斯·门多

1
哦,我刚刚看到:$A
Luis Mendo

2
@LuisMendo Afor Au;)
Fatalize

Aaah,非常好!
路易斯·门多

2

Haskell(Lambdabot),86个字节

f(x,y)=abs$(x/y)-1.618
q n=minimumBy((.f).compare.f)[(x,y)|x<-[1..n],y<-[1..n],x*y==n]

2

php,103个字节

<?php for($s=$a=$argv[1];++$i<$a;)if($a%$i==0&&$s>$t=abs($i*$i/$a-1.618)){$n=$i;$s=$t;}echo"$n ".$a/$n;

产生关于未分配的$ i的通知(不会中断执行),因此应在使通知静音的环境中运行。


当代码可以按以下方式运行时php -r '…'-r无需付费),无需计算PHP open标签。绝对不需要长格式,因为short_open_tag默认情况下已启用。
manatwork's

据我所知$ argv不能与-r一起使用,因此无论如何都不能这样运行。也就是说,如果您在Windows上并且没有标签运行,将其更改为readline()或fgets(STDIN)可能反而会更短。
user59178

-r$argv一起运作良好:pastebin.com/vcgb5pT2
manatwork 2013年

嗯 好吧,它对我不起作用,我只是得到未定义的变量通知,我想知道这是否是设置,或者像往常一样只是窗口。
user59178

您仍然可以替换<?php<?以保存三个字节。
保罗·施米茨

1

Python 3,96个字节

非常简单的解决方案。利用此SO答案

lambda n:min([((i,n//i),abs(1.618-i/(n//i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]

在线尝试

Python 2中的相同解决方案要长一个字节。

lambda n:min([((i,n/i),abs(1.618-1.*i/(n/i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]
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.