查找具有特定LCM和GCD的数字对


9

我当时正在和我的一个朋友一起处理数学问题,我们决定编写一个找到答案的脚本。原始问题如下:

两个自然数的差是2010,而它们的最大公分母是其最小公倍数的2014倍。找到所有可能的解决方案。

我们开始彼此独立地编写程序,当它起作用时,我们决定对其进行优化,以使我们可以管理的字节数最少。我们最终以了惊人的89个字节完成了这段漂亮的代码。

from fractions import*;print[i for i in range(10**6)if i*(i+2010)/gcd(i,i+2010)**2==2014]

我们想看看是否有人能编写较短的代码,该代码枚举了前100万个i。如果您足够勇于竞争,则可以使用任何喜欢的语言,但是我们希望Python 2能够将您的代码与我们的代码进行比较。

通常规则适用,最短字节获胜。适用标准代码的高尔夫球漏洞。标准的“漏洞”不再有趣

玩得开心!


2
@Rainbolt:好的,允许任何语言。python的限制是为了进行比较。但只要您想做就可以:D
sammko

除了3和5092以外,还有其他答案吗?10,000,000之前找不到其他任何内容。
kennytm 2014年

@KennyTM:我有4和5092。是的,我不认为还有其他人。
sammko 2014年

嘿,我已经编辑了您的标题以更好地反映您的要求。如果您觉得我错过了什么,请随时进行更改。
FryAmTheEggman 2014年

顺便删除了python标签。
Timtech,2014年

Answers:


21

Mathematica,8个字节

{4,5092}

证明4和5092是唯一的解决方案:原始问题可以重写为

x(x + 2010)= 2014 GCD(x,x + 2010)2

让我们将x记为2 a 2 3 a 3 5 a 5 …,x + 2010记为2 b 2 3 b 3 5 b 5 …然后,等式变为

2 a 2 + b 2 3 a 3 + b 3 5 a 5 + b 5 …= 2014 2 2min(a 2,b 2 3 2min(a 3,b 3 5 2min(a 5,b 5

自2014年以来= 2×19×53

a p + b p = 2min(a p,b p)+ {1如果p∈{2,19,53},0 else}

从而

一个p = B p如果p≠2,19,53
一个p = B p ±1,否则

从而

x + 2010 = 2 ±1 19 ±1 53 ±1 x

只有8种可能的选择,我们可以轻松地检查4和5092是唯一的正整数解。

等等,我听到人们在尖叫标准漏洞……

Mathematica,45个字节

Select[Range[9^7],2014GCD[#,s=#+2010]^2==s#&]

4

腐霉 27 25

J2010fq+J4/*T+TJ^iTJ2U^T6

在线尝试。

这相当天真地使用了您的算法...我也许可以提出更好的选择...

基本上从中筛选出不符合条件的值 range(10**6)

感谢@xnor在聊天中指出 gcd(x,x+2010)==gcd(x,2010)


3

Python 3,84个字节

FryAmTheEggman's已经提出了如何使您的解决方案达到88字节的建议,因此我不会在此发布。但是我想我将展示如何在Python 3中获得更少的字节:

from fractions import*
x=10**6
while x:y=x+2010;x*y-gcd(x,y)**2*2014or print(x);x-=1

(感谢FryAmTheEggman的提示)

这在Python 2中不起作用,因为print不是函数。

我不确定是否允许,但是如果我们可以使用它9**9代替10**6另一个字节。


我知道有一种方法可以使用and/ or...虽然不会想到python 3;)有关主题的更多信息:如果顺序无关紧要,则我认为设置x=10**6和执行while x:x-=1;...要短一个字节。
FryAmTheEggman 2014年

@FryAmTheEggman从问题的外观看,顺序似乎无关紧要,所以我将其放入。谢谢!
Sp3000

2

R,75个字符

for(a in 1:1e6){q=1:a;b=a+2010;if(a*b/max(q[!a%%q&!b%%q])^2==2014)print(a)}

带换行符:

for(a in 1:1e6){
    q=1:a
    b=a+2010
    if(a*b/max(q[!a%%q&!b%%q])^2==2014)print(a)
    }

2

GolfScript(41个字节)

两个自然数的差是2010,而它们的最大公分母是其最小公倍数的2014倍。找到所有可能的解决方案。

拨打电话号码ambm地点,gcd(a, b) = 1然后写日志b > a。那么区别是m(b-a) = 2010lcm(am, bm) = abm = 2014m依此类推ab=2014

2014年的因素是

1 * 2014
2 * 1007
19 * 106
38 * 53

而那些差异到2010年的是

1007 - 2 => m = 2, solution is 4, 2014
53 - 38 => m = 134, solution is 5092, 7102

由于我使用的语言没有内置的GCD或LCM,因此我认为这种分析可能会缩短程序:

44,{).2014{.2$/\@%!}:,~\2$- 2010,***}%0-`

哪里44floor(sqrt(2014))

使用朴素的循环可能会很接近:

10 6?,1>{.2010+.2${.@\%.}do;.*2014*@@*=},`

所以@KettyTM证明(4,5092)是唯一的解决方案是不正确的?
Optimizer

@Optimizer,您误读了它。他还证明了有两种解决方案,它们与我的解决方案相同。他的证明比我的(IMAO)难得多。
彼得·泰勒

啊,是的。是的,你的比他的更有意义。
Optimizer

2

Perl6 61 58 56 54 52

相当直接地翻译您的资源即可

for ^10**6 ->\i{i.say if i*(i+2010)/(i gcd(i+2010))**2==2014}

gcd 是Perl6中的中缀操作。

^10**6是的缩写0 ..^ 10**6,其中^均值从范围中排除此数字。


当然i gcd (i+2010)是一样的,i gcd 2010所以我可以保存3个字符

for ^10**6 ->\i{i.say if i*(i+2010)/(i gcd 2010)**2==2014}

如果我使用$_代替,i我可以保存另外两个字符。(.say是的缩写$_.say

for ^10**6 {.say if $_*($_+2010)/($_ gcd 2010)**2==2014}

我可以使用... && .say代替来保存另外两个字符.say if ...,因为我不需要&&像我一样在两侧都留有空格if

for ^10**6 {$_*($_+2010)/($_ gcd 2010)**2==2014&&.say}

由于我完成了前面的两个“优化”,因此可以使用的语句修饰符形式for,这意味着我可以删除{}

$_*($_+2010)/($_ gcd 2010)**2==2014&&.say for ^10**6

我认为只要不使用其他算法就可以做到。


2

J,26个字节

   I.((*.=+.*4--)2010+])i.1e6
4 5092

那些该死的2字节动词... :)


1

Dyalog APL,29个字符

      a←⍳10        ⍝ the integers up to 10
      a
1 2 3 4 5 6 7 8 9 10
      2010+a       ⍝ corresponding integers at distance 2010
2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
      a∨2010+a     ⍝ GCD-s between elements of a and 2010+a
1 2 3 2 5 6 1 2 3 10
      ⍝ All APL functions (e.g. + and ∨) are prefix-or-infix, right-associative,
      ⍝ and of the same precedence.
      a∧2010+a     ⍝ LCM-s
2011 2012 2013 4028 2015 2016 14119 8072 6057 2020
      ⍝ For which of them is the LCM 2014 times the GCD?
      (a∧2010+a)=2014×a∨2010+a
0 0 0 1 0 0 0 0 0 0
      ⍝ 0 means false, 1 means true
      ⍝ Filter the elements of "a" corresponding to the 1-s
      ((a∧2010+a)=2014×a∨2010+a) / a
4
      ⍝ Let's abstract this as a function by using curlies.
      ⍝ Omega (⍵) stands for the right argument.
      {((⍵∧2010+⍵)=2014×⍵∨2010+⍵) / ⍵} a
4
      ⍝ Up to a million instead of up to ten:
      {((⍵∧2010+⍵)=2014×⍵∨2010+⍵) / ⍵} ⍳1e6
4 5092
      ⍝ Hey, we can save a few characters by making 2010 the left argument, alpha (⍺)
      2010 {((⍵∧⍺+⍵)=2014×⍵∨⍺+⍵) / ⍵} ⍳1e6
4 5092
      ⍝ Remove a pair of parens by using the switch operator ⍨
      ⍝ An "operator" occurs to the right of a function and modifies its behaviour.
      ⍝ In this case A f⍨ B means the same as B f A
      ⍝ Left and right are swapped, hence "switch".
      2010 {⍵ /⍨ (⍵∧⍺+⍵)=2014×⍵∨⍺+⍵)} ⍳1e6
4 5092
      ⍝ That's 32 characters (modulo whitespace).  Not bad, but we can do better.
      ⍝ A "fork" is a sequence of 3 functions in isolation: f g h
      ⍝ It is evaluated as:  ⍺(f g h)⍵  ←→  (⍺ f ⍵)g(⍺ h ⍵)
      ⍝ If the first item is an array instead of a function: A f g  ←→  {A} f g
      ⍝ Forks are right-associative: f g h k l ←→ f g (h k l)
      2010 {⍵ /⍨ (⍺(⊢∧+)⍵)=2014×(⍺(⊢∨+)⍵)} ⍳1e6
4 5092
      ⍝ The "right tack" function (⊢) simply returns its right argument
      ⍝ Let's abuse forks a little further:
      2010 {⍵ /⍨ ⍺((⊢∧+)=(2014×(⊢∨+)))⍵} ⍳1e6
4 5092
      ⍝ ... and more
      2010 {⍺ (⊢(/⍨)((⊢∧+)=(2014×(⊢∨+)))) ⍵} ⍳1e6
4 5092
      ⍝ But {⍺ f ⍵} is equivalent to f
      2010 (⊢(/⍨)((⊢∧+)=(2014×(⊢∨+)))) ⍳1e6
4 5092
      ⍝ Note that now we are not mentioning ⍺ and ⍵ at all.
      ⍝ This is called "point-free style" or "tacit programming".
      ⍝ Removing some unnecessary parens and whitespace:
      2010(⊢(/⍨)(⊢∧+)=2014×⊢∨+)⍳1e6
4 5092
      ⍝ How many characters?
      ⍴'2010(⊢(/⍨)(⊢∧+)=2014×⊢∨+)⍳1e6'
29

1

PARI / GP,42个字节

[n|n<-[1..8!],2014*gcd(n,t=n+2010)^2==n*t]

我觉得使用GP的fordiv构造有一个非常优雅的解决方案,但是为了简洁起见,它无法与该解决方案竞争。


0

球拍,72个字符

(filter(λ(i)(=(/(*(+ i 2010)i)(expt(gcd(+ i 2010)i)2))2014))(range 1e6))

1
球拍可以和ISO-8859-7一起使用吗?否则我不认为λ是1个字节。
kennytm 2014年

0

Haskell,52个字符

show [x|x<-[1..6^8],x*(x+2010)==2014*(gcd x 2010)^2]

在Haskell交互式环境GHCi中工作。

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.