Tìm các cặp số có LCM và GCD cụ thể


9

Tôi đang làm một câu hỏi toán học với một người bạn của tôi và chúng tôi quyết định viết một kịch bản tìm câu trả lời. Câu hỏi ban đầu như sau:

Sự khác biệt của hai số tự nhiên là năm 2010 và mẫu số chung lớn nhất của chúng nhỏ hơn 2014 lần so với bội số chung thấp nhất của chúng. Tìm tất cả các giải pháp có thể.

Chúng tôi bắt đầu viết chương trình một cách độc lập với nhau và khi nó hoạt động, chúng tôi quyết định chơi nó để có được số byte ít nhất chúng tôi có thể quản lý. Chúng tôi đã kết thúc với dòng mã tuyệt đẹp này với 89 byte tuyệt vời.

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

Chúng tôi muốn xem liệu có ai quản lý để viết một đoạn mã ngắn hơn không, liệt kê 1 triệu đầu tiên của tôi. Nếu bạn đủ can đảm để cạnh tranh, bạn có thể sử dụng bất kỳ ngôn ngữ nào bạn thích, nhưng chúng tôi muốn Python 2 có thể so sánh mã của bạn với ngôn ngữ của chúng tôi.

Quy tắc thông thường áp dụng, byte ngắn nhất giành chiến thắng. Các lỗ hổng golf mã tiêu chuẩn áp dụng. "Lỗ hổng" tiêu chuẩn không còn hài hước

Chúc vui vẻ!


2
@Rainbolt: Ok, cho phép bất kỳ ngôn ngữ. Giới hạn trăn là cho mục đích so sánh. Nhưng chỉ cần làm bất cứ điều gì bạn muốn: D
sammko

Có câu trả lời nào khác ngoài 3 và 5092 không? Không thể tìm thấy bất cứ điều gì khác trước 10.000.000.
kennytm

@KennyTM: Tôi có 4 và 5092. Và vâng, tôi không nghĩ có bất kỳ ai khác.
sammko

Này, tôi đã chỉnh sửa tiêu đề của bạn để phản ánh tốt hơn những gì bạn đang hỏi. Hãy thoải mái thay đổi nó nếu bạn cảm thấy như tôi đã bỏ lỡ điều gì đó.
FryAmTheEggman

Bằng cách loại bỏ thẻ python bằng cách này.
Timtech

Câu trả lời:


21

Toán học, 8 byte

{4,5092}

Bằng chứng rằng 4 và 5092 là giải pháp duy nhất: Vấn đề ban đầu có thể được viết lại thành

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

Hãy viết x là 2 a 2 3 a 3 5 a 5x + 2010 là 2 b 2 3 b 3 5 b 5 khi đó phương trình trở thành

2 một 2 + b 2 3 một 3 + b 3 5 một 5 + b 5 ... = 2014 2 2min (một 2 , b 2 ) 3 2min (một 3 , b 3 ) 5 2min (một 5 , b 5 ) ...

Kể từ 2014 = 2 × 19 × 53, chúng tôi có

a p + b p = 2min (a p , b p ) + {1 nếu p ∈ {2, 19, 53}, 0 khác}

Như vậy

a p = b p nếu p ≠ 2, 19, 53
a p = b p ± 1 khác

Như vậy

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

Chỉ có 8 lựa chọn khả thi và chúng tôi có thể dễ dàng kiểm tra xem 4 và 5092 là các giải pháp số nguyên dương duy nhất.

Đợi đã, tôi nghe thấy tiếng người la hét tiêu chuẩn

Toán học, 45 byte

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

4

Pyth 27 25

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

Hãy thử trực tuyến.

Điều này sử dụng thuật toán của bạn khá ngây thơ ... Tôi có thể có thể tìm ra thứ gì đó tốt hơn ...

Về cơ bản lọc ra các giá trị không đáp ứng tiêu chí từ range(10**6)

Cảm ơn @xnor đã chỉ ra trong trò chuyện mà gcd(x,x+2010)==gcd(x,2010)


3

Python 3, 84 byte

FryAmTheEggman đã đề xuất cách tạo giải pháp của bạn 88 byte để tôi không đăng bài đó. Nhưng tôi nghĩ tôi sẽ chỉ ra cách bạn có thể nhận được ít byte hơn trong Python 3:

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

(Cảm ơn FryAmTheEggman về các mẹo)

Điều này không hoạt động trong Python 2 vì đây printkhông phải là một chức năng.

Tôi không chắc liệu chúng tôi có được phép hay không, nhưng nếu chúng tôi có thể sử dụng 9**9thay vì 10**6đó sẽ là một byte khác.


Tôi biết rằng có một cách để làm điều này với and/ or... sẽ không nghĩ đến python 3;) Thêm về chủ đề: Nếu thứ tự không quan trọng, tôi nghĩ rằng thiết lập x=10**6và thực hiện while x:x-=1;...ngắn hơn một byte.
FryAmTheEggman

@FryAmTheEggman Từ vẻ bề ngoài của câu hỏi, có vẻ như vấn đề không phải là vấn đề nên tôi sẽ đặt nó vào. Cảm ơn!
Sp3000

2

R, 75 ký tự

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

Với ngắt dòng:

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)

Sự khác biệt của hai số tự nhiên là năm 2010 và mẫu số chung lớn nhất của chúng nhỏ hơn 2014 lần so với bội số chung thấp nhất của chúng. Tìm tất cả các giải pháp có thể.

Gọi các số ambmnơi gcd(a, b) = 1và wlog b > a. Sau đó, sự khác biệt là m(b-a) = 2010, và lcm(am, bm) = abm = 2014mnhư vậy ab=2014.

Các yếu tố của năm 2014 là

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

và những người có sự khác biệt chia thành năm 2010 là

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

Vì tôi đang hoạt động với ngôn ngữ không có GCD hoặc LCM tích hợp, tôi nghĩ rằng phân tích này có thể rút ngắn chương trình:

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

nơi 44floor(sqrt(2014)).

Có thể đến khá gần bằng cách sử dụng một vòng lặp ngây thơ:

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

Vậy bằng chứng của @ KettyTM rằng (4,5092) là giải pháp duy nhất không chính xác?
Tối ưu hóa

@Optimizer, bạn đang đọc sai nó. Ông cũng chứng minh rằng có hai giải pháp và chúng giống như giải pháp của tôi. Bằng chứng của anh ta khó theo dõi hơn tôi (IMAO).
Peter Taylor

À, đúng rồi. Và vâng, của bạn có ý nghĩa hơn của anh ấy.
Tối ưu hóa

2

Perl6 61 58 56 54 52

Một bản dịch khá trực tiếp của nguồn của bạn cung cấp

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

gcd là một opix op trong Perl6.

^10**6là viết tắt của 0 ..^ 10**6, trong đó ^phương tiện loại trừ số này khỏi phạm vi.


Tất nhiên i gcd (i+2010)là giống như i gcd 2010vậy để tôi có thể lưu 3 ký tự

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

Nếu tôi sử dụng $_thay vì itôi có thể lưu một vài ký tự khác. ( .sayviết tắt của $_.say)

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

Tôi có thể lưu một vài nhân vật khác bằng cách sử dụng ... && .saythay vì .say if ..., vì tôi không cần một khoảng trống ở cả hai phía &&giống như tôi làm if.

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

Vì tôi đã thực hiện cả hai "tối ưu hóa" trước đó, tôi có thể sử dụng hình thức sửa đổi câu lệnh for, nghĩa là tôi có thể loại bỏ {}.

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

Tôi nghĩ rằng nó ngắn như tôi có thể đi mà không cần sử dụng một thuật toán khác.


2

J, 26 byte

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

Những động từ 2 byte chết tiệt đó ... :)


1

APL Dyalog, 29 ký tự

      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]

Tôi cảm thấy rằng có một giải pháp cực kỳ thanh lịch bằng cách sử dụng fordivcấu trúc của GP nhưng nó không thể cạnh tranh với giải pháp này cho sự ngắn gọn tuyệt đối.


0

Vợt, 72 chars

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

1
Vợt có hoạt động với ISO-8859-7 không? Mặt khác, tôi không nghĩ λlà 1 byte.
kennytm

0

Haskell, 52 ký tự

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

Hoạt động trong môi trường tương tác Haskell GHCi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.