Temukan pasangan angka dengan LCM dan GCD tertentu

9

Saya sedang mengerjakan soal matematika dengan seorang teman saya, dan kami memutuskan untuk menulis naskah yang menemukan jawabannya. Pertanyaan aslinya adalah sebagai berikut:

Perbedaan dari dua bilangan asli adalah 2010 dan penyebut umum terbesarnya adalah 2014 kali lebih kecil dari kelipatan umum terendahnya. Temukan semua solusi yang mungkin.

Kami mulai menulis program secara independen satu sama lain, dan ketika itu berhasil kami memutuskan untuk menambahnya hingga mendapatkan jumlah byte terkecil yang bisa kami kelola. Kami berakhir dengan garis kode yang indah ini dengan 89 byte yang luar biasa.

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

Kami ingin melihat apakah ada yang berhasil menulis kode yang lebih pendek, yang menyebutkan 1 juta i pertama. Jika Anda cukup berani untuk bersaing, Anda dapat menggunakan bahasa apa pun yang Anda suka, tetapi kami lebih suka Python 2 untuk dapat membandingkan kode Anda dengan kami.

Aturan biasa berlaku, byte terpendek menang. Lubang kode golf standar berlaku. Standar "celah" yang tidak lagi lucu

Selamat bersenang-senang!

sammko
sumber
2
@ Rainaint: Ok, diizinkan bahasa apa pun. Keterbatasan python adalah untuk tujuan perbandingan. Tetapi lakukan saja apa yang Anda inginkan: D
sammko
Apakah ada jawaban selain 3 dan 5092? Tidak dapat menemukan yang lain sebelum 10.000.000.
kennytm
@ KennyTM: Saya mendapat 4 dan 5092. Dan ya, saya tidak berpikir ada yang lain.
sammko
Hai, saya telah mengedit judul Anda untuk lebih mencerminkan apa yang Anda minta. Jangan ragu untuk mengubahnya jika Anda merasa saya melewatkan sesuatu.
FryAmTheEggman
Tag python dihapus dengan cara.
Timtech

Jawaban:

21

Mathematica, 8 byte

{4,5092}

Bukti bahwa 4 dan 5092 adalah satu-satunya solusi: Masalah aslinya dapat ditulis ulang sebagai

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

Mari kita menulis x sebagai 2 a 2 3 a 3 5 a 5 ... dan x + 2010 sebagai 2 b 2 3 b 3 5 b 5 ... Kemudian persamaannya menjadi

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

Sejak 2014 = 2 × 19 × 53, kita miliki

a p + b p = 2 mnt (a p , b p ) + {1 jika p ∈ {2, 19, 53}, 0 lainnya}

Jadi

a p = b p jika p ≠ 2, 19, 53
a p = b p ± 1 lainnya

Jadi

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

Hanya ada 8 pilihan yang mungkin, dan kami dapat dengan mudah memeriksa bahwa 4 dan 5092 adalah satu-satunya solusi bilangan bulat positif.

Tunggu, saya mendengar orang-orang menjerit celah standar ...

Mathematica, 45 byte

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

Pyth 27 25

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

Cobalah online.

Ini menggunakan algoritme Anda dengan cukup naif ... Saya mungkin dapat menemukan sesuatu yang lebih baik ...

Pada dasarnya memfilter nilai yang tidak memenuhi kriteria dari range(10**6)

Terima kasih kepada @xnor karena menunjukkan obrolan itu gcd(x,x+2010)==gcd(x,2010)

FryAmTheEggman
sumber
3

Python 3, 84 byte

FryAmTheEggman sudah menyarankan cara membuat solusi Anda 88 byte jadi saya tidak akan memposting itu. Tapi saya pikir saya akan menunjukkan bagaimana Anda bisa mendapatkan byte lebih sedikit di Python 3:

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

(Terima kasih untuk FryAmTheEggman untuk tipnya)

Ini tidak berfungsi di Python 2 karena printitu bukan fungsi.

Saya tidak yakin apakah kami diizinkan, tetapi jika kami bisa menggunakan itu 9**9bukan 10**6byte lain.

Sp3000
sumber
Saya tahu ada cara untuk melakukan ini dengan and/ or... tidak akan pernah memikirkan python 3;) Lebih lanjut tentang topik: Jika pesanan tidak penting, saya pikir pengaturan x=10**6dan melakukan while x:x-=1;...adalah satu byte lebih pendek.
FryAmTheEggman
@FryAmTheEggman Dari pertanyaannya sepertinya tidak penting, jadi saya akan memasukkannya. Terima kasih!
Sp3000
2

R, 75 karakter

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

Dengan jeda baris:

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

GolfScript (41 byte)

Perbedaan dua bilangan asli adalah 2010 dan penyebut umum terbesarnya adalah 2014 kali lebih kecil dari kelipatan umum terendahnya. Temukan semua solusi yang mungkin.

Panggil nomor amdan di bmmana gcd(a, b) = 1serta log b > a. Maka perbedaannya adalah m(b-a) = 2010, dan lcm(am, bm) = abm = 2014msebagainya ab=2014.

Faktor 2014 adalah

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

dan mereka yang memiliki perbedaan yang membagi ke dalam 2010 adalah

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

Karena saya beroperasi dalam bahasa yang tidak memiliki GCD atau LCM bawaan, saya pikir analisis ini mungkin mempersingkat program:

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

di mana 44adalah floor(sqrt(2014)).

Dimungkinkan untuk mendapatkan cukup dekat menggunakan loop naif:

10 6?,1>{.2010+.2${.@\%.}do;.*2014*@@*=},`
Peter Taylor
sumber
Jadi bukti @ KettyTM bahwa (4,5092) adalah satu-satunya solusi yang salah?
Pengoptimal
@Optimizer, Anda salah membaca. Dia juga membuktikan bahwa ada dua solusi, dan mereka sama dengan solusi saya. Buktinya jauh lebih sulit untuk diikuti daripada milikku (IMAO).
Peter Taylor
Ah benar Dan ya, milikmu lebih masuk akal daripada miliknya.
Pengoptimal
2

Perl6 61 58 56 54 52

Terjemahan yang cukup langsung dari sumber Anda berikan

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

gcd adalah infix op di Perl6.

^10**6adalah kependekan 0 ..^ 10**6, di mana ^cara mengecualikan angka ini dari kisaran.


Tentu saja i gcd (i+2010)sama i gcd 2010sehingga saya dapat menyimpan 3 karakter

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

Jika saya menggunakan $_alih-alih, isaya dapat menyimpan beberapa karakter. ( .saykependekan dari $_.say)

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

Saya dapat menyimpan beberapa karakter dengan menggunakan ... && .sayalih-alih .say if ..., karena saya tidak memerlukan ruang di kedua sisi &&seperti yang saya lakukan if.

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

Karena saya melakukan kedua "optimasi" sebelumnya saya dapat menggunakan bentuk pernyataan pengubah for, yang berarti saya dapat menghapus {dan }.

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

Saya pikir itu sesingkat saya bisa pergi tanpa menggunakan algoritma yang berbeda.

Brad Gilbert b2gills
sumber
2

J, 26 byte

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

Kata kerja 2-byte terkutuk itu ... :)

randomra
sumber
1

Dyalog APL, 29 karakter

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

PARI / GP, 42 byte

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

Saya merasa bahwa ada solusi yang sangat elegan menggunakan fordivkonstruksi GP tetapi tidak dapat bersaing dengan solusi ini untuk keringkasan belaka.

Charles
sumber
0

Racket, 72 karakter

(filter(λ(i)(=(/(*(+ i 2010)i)(expt(gcd(+ i 2010)i)2))2014))(range 1e6))
Matthew Butterick
sumber
1
Apakah Racket berfungsi dengan ISO-8859-7? Kalau tidak, saya tidak berpikir λdihitung sebagai 1 byte.
kennytm
0

Haskell, 52 karakter

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

Bekerja di lingkungan interaktif Haskell, GHCi.

pengguna2487951
sumber