Trouver des paires de nombres avec un LCM et un GCD particuliers

9

Je travaillais sur une question mathématique avec un de mes amis, et nous avons décidé d'écrire un script qui trouve la réponse. La question initiale est la suivante:

La différence de deux nombres naturels est 2010 et leur plus grand dénominateur commun est 2014 fois plus petit que leur plus petit multiplicateur commun. Trouvez toutes les solutions possibles.

Nous avons commencé à écrire le programme indépendamment les uns des autres, et quand cela a fonctionné, nous avons décidé de le jouer pour obtenir le moins d'octets possible. Nous nous sommes retrouvés avec cette belle ligne de code à un merveilleux 89 octets.

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

Nous voulions voir si quelqu'un parvient à écrire un morceau de code plus court, qui énumère les 1 million de premiers i. Si vous êtes assez courageux pour concurrencer, vous pouvez utiliser n'importe quelle langue que vous aimez, mais nous préférerions que Python 2 puisse comparer votre code avec le nôtre.

Les règles habituelles s'appliquent, les octets les plus courts gagnent. Les failles de golf à code standard s'appliquent. Des "failles" standard qui ne sont plus drôles

S'amuser!

sammko
la source
2
@Rainbolt: Ok, autorisé n'importe quelle langue. La limitation de python était à des fins de comparaison. Mais faites ce que vous voulez: D
sammko
Y a-t-il des réponses autres que 3 et 5092? Je ne trouve rien d'autre avant 10 000 000.
kennytm
@KennyTM: J'ai 4 et 5092. Et oui, je ne pense pas qu'il y en ait d'autres.
sammko
Hé, j'ai édité votre titre pour mieux refléter ce que vous demandez. N'hésitez pas à le changer si vous sentez que j'ai raté quelque chose.
FryAmTheEggman
Suppression de la balise python en passant.
Timtech

Réponses:

21

Mathematica, 8 octets

{4,5092}

Preuve que 4 et 5092 sont les seules solutions: le problème d'origine peut être réécrit comme

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

Écrivons x comme 2 a 2 3 a 3 5 a 5 … et x + 2010 comme 2 b 2 3 b 3 5 b 5 … Alors l'équation devient

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 )

Depuis 2014 = 2 × 19 × 53, nous avons

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

Donc

a p = b p si p ≠ 2, 19, 53
a p = b p ± 1 sinon

Donc

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

Il n'y a que 8 choix possibles, et nous pourrions facilement vérifier que 4 et 5092 sont les seules solutions entières positives.

Attendez, j'entends des gens crier échappatoire standard…

Mathematica, 45 octets

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

Pyth 27 25

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

Essayez-le en ligne.

Cela utilise votre algorithme assez naïvement ... Je pourrais peut-être trouver quelque chose de mieux ...

Filtre essentiellement les valeurs qui ne répondent pas au critère de range(10**6)

Merci à @xnor d'avoir signalé dans le chat que gcd(x,x+2010)==gcd(x,2010)

FryAmTheEggman
la source
3

Python 3, 84 octets

FryAmTheEggman a déjà suggéré comment rendre votre solution 88 octets donc je ne posterai pas cela. Mais je pensais montrer comment vous pouvez obtenir encore moins d'octets en Python 3:

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

(Merci pour FryAmTheEggman pour les conseils)

Cela ne fonctionne pas en Python 2 car ce printn'est pas une fonction.

Je ne sais pas si nous sommes autorisés, mais si nous pouvions utiliser à la 9**9place, 10**6ce serait un autre octet.

Sp3000
la source
Je savais qu'il y avait un moyen de le faire avec and/ or... n'aurait pas pensé python 3 bien;) Plus sur le sujet: Si l' ordre n'a pas d' importance, je pense que la mise x=10**6et de faire while x:x-=1;...est un octet plus courte.
FryAmTheEggman
@FryAmTheEggman D'après l'apparence de la question, il ne semble pas que l'ordre compte, alors je vais le mettre. Merci!
Sp3000
2

R, 75 caractères

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

Avec des sauts de ligne:

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

GolfScript (41 octets)

La différence de deux nombres naturels est 2010 et leur plus grand dénominateur commun est 2014 fois plus petit que leur plus petit commun multiple. Trouvez toutes les solutions possibles.

Appelez les numéros amet bmgcd(a, b) = 1et wlog b > a. Alors la différence est m(b-a) = 2010, et lcm(am, bm) = abm = 2014mainsi ab=2014.

Les facteurs de 2014 sont

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

et ceux qui ont des différences qui se divisent en 2010 sont

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

Comme je travaille dans une langue qui n'a pas de GCD ou LCM intégré, je pense que cette analyse raccourcit probablement le programme:

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

44est floor(sqrt(2014)).

Il est possible de se rapprocher assez en utilisant une boucle naïve:

10 6?,1>{.2010+.2${.@\%.}do;.*2014*@@*=},`
Peter Taylor
la source
Donc, la preuve de @ KettyTM que (4 5092) est la seule solution est incorrecte?
Optimizer
@Optimizer, vous l'avez mal lu. Il prouve également qu'il y a deux solutions, et ce sont les mêmes que mes solutions. Sa preuve est juste beaucoup plus difficile à suivre que la mienne (IMAO).
Peter Taylor
Ah, c'est vrai. Et oui, le vôtre a plus de sens que le sien.
Optimizer
2

Perl6 61 58 56 54 52

Une traduction assez directe de votre source donne

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

gcd est une infixation op en Perl6.

^10**6est l'abréviation de 0 ..^ 10**6, où les ^moyennes excluent ce nombre de la plage.


Bien sûr, i gcd (i+2010)c'est la même chose que i gcd 2010je peux enregistrer 3 caractères

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

Si j'utilise $_au lieu de ije peux enregistrer un autre couple de caractères. ( .sayest l'abréviation de $_.say)

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

Je peux enregistrer un autre couple de caractères en utilisant ... && .sayau lieu de .say if ..., car je n'ai pas besoin d'espace des deux côtés &&comme je le fais pour if.

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

Depuis que j'ai fait les deux "optimisations" précédentes, je peux utiliser le formulaire de modification d'instructions de for, ce qui signifie que je peux supprimer {et }.

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

Je pense que c'est aussi court que possible sans utiliser un algorithme différent.

Brad Gilbert b2gills
la source
2

J, 26 octets

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

Ces damnés verbes à 2 octets ... :)

randomra
la source
1

Dyalog APL, 29 caractères

      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
la source
1

PARI / GP, 42 octets

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

Je pense qu'il existe une solution extrêmement élégante utilisant la fordivconstruction de GP, mais elle ne pouvait pas rivaliser avec cette solution pour la brièveté.

Charles
la source
0

Raquette, 72 caractères

(filter(λ(i)(=(/(*(+ i 2010)i)(expt(gcd(+ i 2010)i)2))2014))(range 1e6))
Matthew Butterick
la source
1
La raquette fonctionne-t-elle avec ISO-8859-7? Sinon, je ne pense pas que ça λcompte comme 1 octet.
kennytm
0

Haskell, 52 caractères

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

Fonctionne dans l'environnement interactif Haskell GHCi.

user2487951
la source