Trova coppie di numeri con un particolare LCM e GCD


9

Stavo lavorando a una domanda di matematica con un mio amico e abbiamo deciso di scrivere una sceneggiatura che trova la risposta. La domanda originale è la seguente:

La differenza tra due numeri naturali è il 2010 e il loro massimo comune denominatore è 2014 volte più piccolo del loro minimo comune moltiplicarsi. Trova tutte le possibili soluzioni.

Abbiamo iniziato a scrivere il programma indipendentemente l'uno dall'altro, e quando ha funzionato abbiamo deciso di giocarci su per ottenere il minor numero di byte che potevamo gestire. Abbiamo finito con questa bellissima riga di codice a 89 byte meravigliosi.

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

Volevamo vedere se qualcuno riesce a scrivere un pezzo di codice più breve, che elenca i primi 1 milione di i. Se sei abbastanza coraggioso da competere, puoi usare qualsiasi linguaggio tu voglia, ma preferiremmo Python 2 per poter confrontare il tuo codice con il nostro.

Si applicano le solite regole, vincono i byte più brevi. Si applicano le scappatoie da golf di codice standard. "Scappatoie" standard che non sono più divertenti

Divertiti!


2
@Rainbolt: Ok, ha permesso qualsiasi lingua. La limitazione di Python era a scopo di confronto. Ma fai quello che vuoi: D
sammko,

Ci sono risposte diverse da 3 e 5092? Non è stato possibile trovare altro prima di 10.000.000.
kennytm,

@KennyTM: ho ottenuto 4 e 5092. E sì, non credo che ce ne siano altri.
Sammko,

Ehi, ho modificato il tuo titolo per riflettere meglio ciò che stai chiedendo. Sentiti libero di cambiarlo se ritieni di aver perso qualcosa.
FryAmTheEggman,

Rimosso tag python a proposito.
Timtech,

Risposte:


21

Mathematica, 8 byte

{4,5092}

Prova che 4 e 5092 sono le uniche soluzioni: il problema originale può essere riscritto come

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

Scriviamo x come 2 a 2 3 a 3 5 a 5 … e x + 2010 come 2 b 2 3 b 3 5 b 5 … Quindi l'equazione diventa

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 ) ...

Dal 2014 = 2 × 19 × 53, abbiamo

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

così

a p = b p se p ≠ 2, 19, 53
a p = b p ± 1 altro

così

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

Ci sono solo 8 possibili scelte e potremmo facilmente verificare che 4 e 5092 siano le uniche soluzioni intere positive.

Aspetta, sento gente urlare scappatoia standard ...

Mathematica, 45 byte

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

4

Pyth 27 25

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

Provalo online.

Questo usa il tuo algoritmo in modo abbastanza ingenuo ... Potrei essere in grado di trovare qualcosa di meglio ...

Fondamentalmente filtra i valori che non soddisfano il criterio da range(10**6)

Grazie a @xnor per averlo sottolineato in chat gcd(x,x+2010)==gcd(x,2010)


3

Python 3, 84 byte

FryAmTheEggman ha già suggerito come rendere la tua soluzione di 88 byte, quindi non la posterò. Ma ho pensato di mostrare come è possibile ottenere ancora meno byte in Python 3:

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

(Grazie per FryAmTheEggman per i suggerimenti)

Questo non funziona in Python 2 perché printnon è una funzione.

Non sono sicuro che ci sia permesso, ma se potessimo usare al 9**9posto di 10**6quello sarebbe un altro byte.


Sapevo che c'era un modo per farlo con and/ or... non avrei pensato a Python 3;) Altro sull'argomento: Se l'ordine non ha importanza, penso che l'impostazione x=10**6e l'esecuzione while x:x-=1;...siano più brevi di un byte.
FryAmTheEggman,

@FryAmTheEggman Dall'aspetto della domanda non sembra che l'ordine sia importante, quindi lo inserirò. Grazie!
Sp3000,

2

R, 75 caratteri

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

Con interruzioni di riga:

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 byte)

La differenza tra due numeri naturali è il 2010 e il loro massimo comune denominatore è 2014 volte più piccolo del loro minimo comune multiplo. Trova tutte le possibili soluzioni.

Chiama i numeri ame bmdove gcd(a, b) = 1e wlog b > a. Quindi la differenza è m(b-a) = 2010, e lcm(am, bm) = abm = 2014mcosì ab=2014.

I fattori del 2014 sono

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

e quelli che hanno differenze che si dividono nel 2010 lo sono

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

Dato che sto operando in un linguaggio che non ha GCD o LCM integrato, penso che questa analisi probabilmente accorcia il programma:

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

dove 44è floor(sqrt(2014)).

È possibile avvicinarsi abbastanza usando un ciclo ingenuo:

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

Quindi la prova di @ KettyTM che (4,5092) è l'unica soluzione non è corretta?
Ottimizzatore

@Optimizer, stai leggendo male. Dimostra anche che ci sono due soluzioni e sono le stesse delle mie soluzioni. La sua prova è solo molto più difficile da seguire della mia (IMAO).
Peter Taylor,

Ah vero. E sì, il tuo ha più senso del suo.
Ottimizzatore

2

Perl6 61 58 56 54 52

Dà una traduzione abbastanza diretta della tua fonte

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

gcd è un'operazione infix in Perl6.

^10**6è l'abbreviazione di 0 ..^ 10**6, dove i ^mezzi escludono questo numero dall'intervallo.


Ovviamente i gcd (i+2010)è lo stesso, i gcd 2010quindi posso salvare 3 personaggi

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

Se uso $_invece di iposso salvare un altro paio di personaggi. ( .sayè l'abbreviazione di $_.say)

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

Posso salvare un altro paio di personaggi usando ... && .sayinvece di .say if ..., perché non ho bisogno di uno spazio su entrambi i lati &&come faccio per if.

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

Dato che ho fatto entrambe le "ottimizzazioni" precedenti, posso usare il modulo modificatore di istruzione di for, il che significa che posso rimuovere {e }.

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

Penso che sia il più breve possibile senza usare un algoritmo diverso.


2

J, 26 byte

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

Quei dannati verbi a 2 byte ... :)


1

Dyalog APL, 29 personaggi

      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 byte

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

Sento che esiste una soluzione estremamente elegante usando il fordivcostrutto di GP ma non potrebbe competere con questa soluzione per pura brevità.


0

Racchetta, 72 caratteri

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

1
La racchetta funziona con ISO-8859-7? Altrimenti non penso che λvalga 1 byte.
kennytm,

0

Haskell, 52 caratteri

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

Funziona nell'ambiente interattivo Haskell GHCi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.