Знайдіть пари чисел із певним LCM та GCD


9

Я працював над математичним питанням зі своїм другом, і ми вирішили написати сценарій, який знайде відповідь. Оригінальне запитання таке:

Різниця двох натуральних чисел - 2010 рік, а їх найбільший спільний знаменник у 2014 році менший за їх найменше спільне множення. Знайдіть усі можливі рішення.

Ми почали писати програму незалежно один від одного, і коли вона спрацювала, ми вирішили переграти її, щоб отримати найменшу кількість байтів, якими ми могли керувати. Ми закінчилися цим прекрасним рядком коду у дивовижних 89 байт.

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

Ми хотіли побачити, чи вдасться кому-небудь написати коротший фрагмент коду, який перераховує перші 1 мільйон я. Якщо ви досить сміливі, щоб змагатися, ви можете використовувати будь-яку мову, яка вам подобається, але ми вважаємо за краще Python 2, щоб можна було порівнювати ваш код з нашим.

Звичайні правила діють, виграють найкоротші байти. Діють стандартні лазівки для гольфу. Стандартні "лазівки", які вже не смішні

Веселіться!


2
@Rainbolt: Гаразд, дозволена будь-яка мова. Обмеження пітона було для порівняння. Але просто робіть все, що завгодно: D
sammko

Чи є відповіді, крім 3 та 5092? Не можу знайти нічого іншого до 10 000 000.
kennytm

@KennyTM: У мене 4 і 5092. І так, я не думаю, що є інші.
саммко

Гей, я відредагував ваш заголовок, щоб краще відобразити те, що ви просите. Не соромтеся змінити це, якщо відчуєте, що я щось пропустив.
FryAmTheEggman

До речі, тег python видалено.
Timtech

Відповіді:


21

Математика, 8 байт

{4,5092}

Доказ того, що 4 та 5092 - єдине рішення: Оригінальну проблему можна переписати як

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

Запишемо x як 2 a 2 3 a 3 5 a 5 … і x + 2010 як 2 b 2 3 b 3 5 b 5 … Тоді рівняння стає

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 )

З 2014 року = 2 × 19 × 53, маємо

a p + b p = 2min (a p , b p ) + {1, якщо p ∈ {2, 19, 53}, 0 else}

Таким чином

a p = b p, якщо p ≠ 2, 19, 53
a p = b p ± 1 інакше

Таким чином

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

Є лише 8 можливих варіантів, і ми можемо легко перевірити, що 4 та 5092 є єдиними цілими рішеннями з цілим числом.

Зачекайте, я чую, як люди кричать стандартну лазівку ...

Математика, 45 байт

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

4

Піф 27 25

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

Спробуйте в Інтернеті.

Це використовує ваш алгоритм досить наївно ... Я, можливо, зможу придумати щось краще ...

В основному фільтруються значення, які не відповідають критерію range(10**6)

Дякуємо @xnor за те, що вказав у чаті на це gcd(x,x+2010)==gcd(x,2010)


3

Пітон 3, 84 байти

FryAmTheEggman вже запропонував, як зробити ваше рішення 88 байтів, тому я цього не публікую. Але я подумав, що я покажу, як ви можете отримати ще менше байтів у Python 3:

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

(Дякую FryAmTheEggman за поради)

Це не працює в Python 2, оскільки printце не функція.

Я не впевнений, чи нам це дозволено, але якби ми могли використати 9**9замість цього 10**6, був би інший байт.


Я знав, що є спосіб зробити це з and/ or... не подумав би про python 3, хоча;) Більше на тему: Якщо порядок не має значення, я думаю, що налаштування x=10**6і виконання while x:x-=1;...на один байт коротше.
FryAmTheEggman

@FryAmTheEggman З вигляду питання це не здається, що питання має значення, тому я поставлю це. Дякую!
Sp3000

2

R, 75 символів

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

З розривами рядків:

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 байт)

Різниця двох натуральних чисел - 2010 рік, а їх найбільший спільний знаменник у 2014 році менший від їх найменшого загального кратного. Знайдіть усі можливі рішення.

Виклик номера amі bmде gcd(a, b) = 1і без втрати спільності b > a. Тоді різниця є m(b-a) = 2010, і lcm(am, bm) = abm = 2014mтак ab=2014.

Фактори 2014 року є

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

і ті, які мають відмінності, поділяються на 2010 рік

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

Оскільки я працюю мовою, яка не має вбудованого GCD або LCM, я думаю, що цей аналіз, ймовірно, скорочує програму:

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

де 44є floor(sqrt(2014)).

Можна досить близько наблизитися за допомогою наївного циклу:

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

Тож доказ @ KettyTM про те, що (4,5092) є єдиним рішенням, невірно?
Оптимізатор

@Optimizer, ви неправильно його читаєте. Він також доводить, що є два рішення, і вони такі ж, як і мої рішення. Його доказ просто набагато важче переслідувати, ніж мій (IMAO).
Пітер Тейлор

Ах, правда. І так, ваш має більше сенсу, ніж його.
Оптимізатор

2

Perl6 61 58 56 54 52

Досить прямий переклад вашого джерела дає

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

gcd є опцією інфікування в Perl6.

^10**6скорочено 0 ..^ 10**6, де ^засоби виключають це число з діапазону.


Звичайно i gcd (i+2010), те саме, що i gcd 2010я можу зберегти 3 символи

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

Якщо я використовую $_замість цього, iя можу зберегти ще пару символів. ( .sayскорочено $_.say)

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

Я можу зберегти ще пару символів, використовуючи ... && .sayзамість цього .say if ..., тому що мені не потрібно місця з обох сторін, &&як я роблю if.

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

Оскільки я зробив обидві попередні "оптимізації", я можу використовувати форму модифікатора висловлювань for, що означає, що я можу видалити {і }.

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

Я думаю, що це так коротко, як я можу йти без використання іншого алгоритму.



1

Діалог APL, 29 символів

      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 байти

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

Я вважаю, що існує надзвичайно елегантне рішення за допомогою fordivконструкції GP, але воно не могло конкурувати з цим рішенням для чистоти.


0

Ракетка, 72 символи

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

1
Чи працює Ракетка з ISO-8859-7? Інакше я не думаю, що λвважається 1 байтом.
kennytm

0

Хаскелл, 52 ч

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

Працює в інтерактивному середовищі Haskell GHCi.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.