Finden Sie Zahlenpaare mit einem bestimmten LCM und GCD

9

Ich habe mit einem Freund an einer mathematischen Frage gearbeitet, und wir haben beschlossen, ein Skript zu schreiben, das die Antwort findet. Die ursprüngliche Frage lautet wie folgt:

Die Differenz zweier natürlicher Zahlen ist 2010 und ihr größter gemeinsamer Nenner ist 2014 mal kleiner als ihre niedrigste gemeinsame Multiplikation. Finden Sie alle möglichen Lösungen.

Wir haben angefangen, das Programm unabhängig voneinander zu schreiben, und als es funktionierte, haben wir beschlossen, es zu spielen, um die geringste Anzahl von Bytes zu erhalten, die wir verwalten konnten. Wir haben diese wunderschöne Codezeile mit wunderbaren 89 Bytes erhalten.

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

Wir wollten sehen, ob es jemandem gelingt, einen kürzeren Code zu schreiben, der die ersten 1 Million i auflistet. Wenn Sie mutig genug sind, sich zu behaupten, können Sie eine beliebige Sprache verwenden. Wir würden jedoch Python 2 bevorzugen, um Ihren Code mit unserem vergleichen zu können.

Es gelten die üblichen Regeln, kürzeste Bytes gewinnen. Es gelten die Standardcode-Golfschlupflöcher. Standard "Lücken", die nicht mehr lustig sind

Habe Spaß!

sammko
quelle
2
@ Rainbolt: Ok, jede Sprache erlaubt. Die Python-Beschränkung diente zu Vergleichszwecken. Aber mach einfach was du willst: D
sammko
Gibt es andere Antworten als 3 und 5092? Ich kann vor 10.000.000 nichts anderes finden.
Kennytm
@KennyTM: Ich habe 4 und 5092. Und ja, ich glaube nicht, dass es noch andere gibt.
Sammko
Hey, ich habe deinen Titel bearbeitet, um besser zu reflektieren, was du fragst. Sie können es jederzeit ändern, wenn Sie das Gefühl haben, etwas verpasst zu haben.
FryAmTheEggman
Python-Tag übrigens entfernt.
Timtech

Antworten:

21

Mathematica, 8 Bytes

{4,5092}

Beweis, dass 4 und 5092 die einzigen Lösungen sind: Das ursprüngliche Problem kann wie folgt umgeschrieben werden

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

Schreiben wir x als 2 a 2 3 a 3 5 a 5 … und x + 2010 als 2 b 2 3 b 3 5 b 5 … Dann wird die Gleichung

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

Seit 2014 = 2 × 19 × 53 haben wir

a p + b p = 2 min (a p , b p ) + {1 wenn p ∈ {2, 19, 53}, 0 sonst}

Somit

a p = b p wenn p ≠ 2, 19, 53
a p = b p ± 1 sonst

Somit

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

Es gibt nur 8 mögliche Auswahlmöglichkeiten, und wir können leicht überprüfen, ob 4 und 5092 die einzigen positiven ganzzahligen Lösungen sind.

Warten Sie, ich höre Leute Standardlücke schreien ...

Mathematica, 45 Bytes

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

Pyth 27 25

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

Probieren Sie es online aus.

Dies verwendet Ihren Algorithmus ziemlich naiv ... Ich könnte mir etwas Besseres einfallen lassen ...

Filtert grundsätzlich Werte aus, die das Kriterium nicht erfüllen range(10**6)

Vielen Dank an @xnor für den Hinweis im Chat gcd(x,x+2010)==gcd(x,2010)

FryAmTheEggman
quelle
3

Python 3, 84 Bytes

FryAmTheEggman hat bereits vorgeschlagen, wie Sie Ihre Lösung auf 88 Byte bringen können, damit ich das nicht poste. Aber ich dachte, ich würde zeigen, wie Sie in Python 3 noch weniger Bytes erhalten können:

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

(Danke für FryAmTheEggman für Tipps)

Dies funktioniert in Python 2 nicht, da es printkeine Funktion ist.

Ich bin mir nicht sicher, ob wir erlaubt sind, aber ob wir 9**9stattdessen verwenden könnten 10**6, wäre ein weiteres Byte.

Sp3000
quelle
Ich wusste, dass es einen Weg gibt, dies mit and/ or... zu tun, hätte aber nicht an Python 3 gedacht;) Mehr zum Thema: Wenn die Reihenfolge keine Rolle spielt, denke ich, dass das Einstellen x=10**6und Ausführen while x:x-=1;...ein Byte kürzer ist.
FryAmTheEggman
@FryAmTheEggman Nach dem Aussehen der Frage scheint es nicht wichtig zu sein, also werde ich das einfügen. Danke!
Sp3000
2

R, 75 Zeichen

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

Mit Zeilenumbrüchen:

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

GolfScript (41 Bytes)

Die Differenz zweier natürlicher Zahlen ist 2010 und ihr größter gemeinsamer Nenner ist 2014 mal kleiner als ihr niedrigstes gemeinsames Vielfaches. Finden Sie alle möglichen Lösungen.

Rufen Sie die Nummern amund bmwo gcd(a, b) = 1und wlog b > a. Dann ist der Unterschied m(b-a) = 2010und lcm(am, bm) = abm = 2014mso ab=2014.

Faktoren von 2014 sind

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

und diejenigen, die Unterschiede haben, die sich in 2010 teilen, sind

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

Da ich in einer Sprache arbeite, in der weder GCD noch LCM integriert sind, verkürzt diese Analyse wahrscheinlich das Programm:

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

wo 44ist floor(sqrt(2014)).

Es ist möglich, mit einer naiven Schleife ganz nah zu kommen:

10 6?,1>{.2010+.2${.@\%.}do;.*2014*@@*=},`
Peter Taylor
quelle
Der Beweis von @ KettyTM, dass (4.5092) die einzige Lösung ist, ist also falsch?
Optimierer
@Optimizer, du liest es falsch. Er beweist auch, dass es zwei Lösungen gibt, die mit meinen Lösungen identisch sind. Sein Beweis ist nur viel schwerer zu verfolgen als meiner (IMAO).
Peter Taylor
Ah, stimmt. Und ja, deine macht mehr Sinn als seine.
Optimierer
2

Perl6 61 58 56 54 52

Eine ziemlich direkte Übersetzung Ihrer Quelle gibt

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

gcd ist ein Infix op in Perl6.

^10**6ist die Abkürzung für 0 ..^ 10**6, wobei die ^Mittel diese Zahl aus dem Bereich ausschließen.


Natürlich i gcd (i+2010)ist das das gleiche wie i gcd 2010so kann ich 3 Zeichen speichern

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

Wenn ich $_anstelle von verwende, ikann ich noch ein paar Zeichen speichern. ( .sayist die Abkürzung für $_.say)

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

Ich kann ein paar weitere Zeichen speichern, indem ich ... && .sayanstelle von verwende .say if ..., da ich auf beiden Seiten kein Leerzeichen benötige, &&wie ich es tue if.

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

Da ich beide vorherigen "Optimierungen" durchgeführt habe, kann ich die Anweisungsmodifikatorform von verwenden for, was bedeutet, dass ich {und entfernen kann }.

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

Ich denke, das ist so kurz wie möglich, ohne einen anderen Algorithmus zu verwenden.

Brad Gilbert b2gills
quelle
2

J, 26 Bytes

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

Diese verdammten 2-Byte-Verben ... :)

randomra
quelle
1

Dyalog APL, 29 Zeichen

      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
ngn
quelle
1

PARI / GP, 42 Bytes

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

Ich bin der Meinung, dass es eine äußerst elegante Lösung gibt, die das fordivKonstrukt von GP verwendet, aber mit dieser Lösung konnte sie aus Gründen der Kürze nicht mithalten.

Charles
quelle
0

Schläger, 72 Zeichen

(filter(λ(i)(=(/(*(+ i 2010)i)(expt(gcd(+ i 2010)i)2))2014))(range 1e6))
Matthew Butterick
quelle
1
Funktioniert Racket mit ISO-8859-7? Ansonsten zählt meiner Meinung nach nicht λ1 Byte.
Kennytm
0

Haskell, 52 Zeichen

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

Funktioniert in der interaktiven Haskell-Umgebung GHCi.

user2487951
quelle