Encontre pares de números com um determinado LCM e GCD

9

Eu estava trabalhando em uma pergunta de matemática com um amigo meu e decidimos escrever um script que encontrasse a resposta. A pergunta original é a seguinte:

A diferença de dois números naturais é 2010 e seu maior denominador comum é 2014 vezes menor que a menor multiplicação comum. Encontre todas as soluções possíveis.

Começamos a escrever o programa independentemente um do outro e, quando funcionou, decidimos aumentar o número de bytes que pudéssemos gerenciar. Acabamos com essa bela linha de código em maravilhosos 89 bytes.

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

Queríamos ver se alguém consegue escrever um pedaço de código mais curto, que enumere os primeiros 1 milhão de i's. Se você for corajoso o suficiente para competir, poderá usar qualquer idioma que desejar, mas preferimos o Python 2 para poder comparar seu código com o nosso.

Aplicam-se regras usuais, os bytes mais curtos vencem. Aplicam-se as brechas de golfe com código padrão. "Brechas" padrão que não são mais engraçadas

Diverta-se!

sammko
fonte
2
@Rainbolt: Ok, é permitido qualquer idioma. A limitação do python foi para fins de comparação. Mas faça o que você quiser: D
sammko 11/11/14
Existem respostas diferentes de 3 e 5092? Não é possível encontrar mais nada antes de 10.000.000.
Kennytm
@KennyTM: Eu tenho 4 e 5092. E sim, acho que não existem outros.
sammko
Ei, editei seu título para refletir melhor o que você está perguntando. Sinta-se livre para alterá-lo se você sentir que eu perdi alguma coisa.
FryAmTheEggman
Removida a tag python, a propósito.
Timtech

Respostas:

21

Mathematica, 8 bytes

{4,5092}

Prova de que 4 e 5092 são as únicas soluções: O problema original pode ser reescrito como

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

Vamos escrever x como 2 a 2 3 a 3 5 a 5 … e x + 2010 como 2 b 2 3 b 3 5 b 5 … Então a equação se torna

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 )

Desde 2014 = 2 × 19 × 53, temos

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

portanto

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

portanto

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

Existem apenas 8 opções possíveis, e poderíamos facilmente verificar se 4 e 5092 são as únicas soluções inteiras positivas.

Espere, eu ouço pessoas gritando brecha padrão ...

Mathematica, 45 bytes

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

Pitão 27 25

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

Experimente online.

Isso usa seu algoritmo de forma bastante ingênua ... Talvez eu consiga criar algo melhor ...

Filtra basicamente valores que não atendem ao critério de range(10**6)

Obrigado a @xnor por apontar no bate-papo que gcd(x,x+2010)==gcd(x,2010)

FryAmTheEggman
fonte
3

Python 3, 84 bytes

O FryAmTheEggman já sugeriu como fazer sua solução 88 bytes, para que eu não publique isso. Mas pensei em mostrar como você pode obter ainda menos bytes no Python 3:

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

(Obrigado por FryAmTheEggman pelas dicas)

Isso não funciona no Python 2 porque printnão é uma função.

Não tenho certeza se somos permitidos, mas se pudéssemos usar em 9**9vez 10**6disso, seria outro byte.

Sp3000
fonte
Eu sabia que havia uma maneira de fazer isso com and/ or... não teria pensado no python 3;) Mais sobre o tópico: Se a ordem não importa, acho que definir x=10**6e fazer while x:x-=1;...é um byte mais curto.
FryAmTheEggman
@FryAmTheEggman Do ponto de vista da pergunta, não parece que a ordem seja importante, então vou colocar isso. Obrigado!
Sp3000
2

R, 75 caracteres

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

Com quebras de linha:

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
fonte
2

GolfScript (41 bytes)

A diferença de dois números naturais é 2010 e seu maior denominador comum é 2014 vezes menor que o menor múltiplo comum. Encontre todas as soluções possíveis.

Ligue para os números ame bmwhere gcd(a, b) = 1e wlog b > a. Então a diferença é m(b-a) = 2010, e lcm(am, bm) = abm = 2014massim ab=2014.

Fatores de 2014 são

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

e aqueles que têm diferenças que se dividem em 2010 são

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

Como estou operando em um idioma que não possui GCD ou LCM embutido, acho que essa análise provavelmente reduz o programa:

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

onde 44é floor(sqrt(2014)).

É possível chegar bem perto usando um loop ingênuo:

10 6?,1>{.2010+.2${.@\%.}do;.*2014*@@*=},`
Peter Taylor
fonte
Então a prova do @ KettyTM de que (4.5092) é a única solução incorreta?
Optimizer
@ Otimizador, você está lendo errado. Ele também prova que existem duas soluções e são as mesmas que as minhas. A prova dele é muito mais difícil de seguir do que a minha (IMAO).
Peter Taylor
Ah verdade. E sim, o seu faz mais sentido que o dele.
Optimizer
2

Perl6 61 58 56 54 52

Uma tradução bastante direta da sua fonte fornece

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

gcd é um infix op no Perl6.

^10**6é a abreviação de 0 ..^ 10**6, onde os ^meios excluem esse número do intervalo.


Claro que i gcd (i+2010)é o mesmo que i gcd 2010eu posso salvar 3 caracteres

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

Se eu usar em $_vez de i, posso salvar outro par de caracteres. ( .sayé a abreviação de $_.say)

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

Posso salvar outros caracteres usando em ... && .sayvez de .say if ..., porque não preciso de espaço nos dois lados, &&como faço para if.

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

Desde que eu fiz as duas "otimizações" anteriores, posso usar o modificador de declaração de for, o que significa que posso remover {e }.

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

Eu acho que é o mais curto possível sem usar um algoritmo diferente.

Brad Gilbert b2gills
fonte
2

J, 26 bytes

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

Esses malditos verbos de 2 bytes ... :)

randomra
fonte
1

Dyalog APL, 29 caracteres

      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
fonte
1

PARI / GP, 42 bytes

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

Eu sinto que existe uma solução extremamente elegante usando a fordivconstrução do GP, mas ela não poderia competir com essa solução por pura brevidade.

Charles
fonte
0

Raquete, 72 caracteres

(filter(λ(i)(=(/(*(+ i 2010)i)(expt(gcd(+ i 2010)i)2))2014))(range 1e6))
Matthew Butterick
fonte
11
A raquete funciona com ISO-8859-7? Caso contrário, acho que não λconta como 1 byte.
Kennytm
0

Haskell, 52 caracteres

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

Trabalha no ambiente interativo Haskell GHCi.

user2487951
fonte