Напишіть програму, яка підтверджує гіпотезу Ерда – Строса


15

Напишіть програму, яка підтверджує гіпотезу Ерда – Строса .
Програма повинна прийняти в якості вхідних даних одне цілого числа n( 3 <= n <= 1 000 000) і друк трійки цілих чисел , що задовольняють ідентичність 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

Найкоротший код виграє.

Деякі приклади:

3 => {1, 4, 12}
4 => {2, 3, 6}
5 => {2, 4, 20}
1009 => {253, 85096, 1974822872}
999983 => {249996, 249991750069, 62495875102311369754692}
1000000 => {500000, 750000, 1500000}

Зауважте, що ваша програма може надрукувати інші результати для цих номерів, оскільки існує кілька рішень.


Чи потрібно програмі виводити кожне можливе рішення або лише одне? Наприклад, є 2 можливості для n = 5.
izlin

1
Достатньо лише одного.
Сомній

2
Дещо вводить в оману те, що ваш єдиний тестовий випадок не є коректною інформацією відповідно до специфікації.
Пітер Тейлор

Я його зміню, наприклад додав durron597.
Сомній

Я додав цей приклад, тому що моє дослідження припустило, що це було особливо важко зробити. Найскладнішими є праймери, що відповідають {1, 121, 169, 289, 361, 529}модулі 840.
durron597

Відповіді:


12

Рубі, 119 106 символів

f=->s,c,a{m=s.to_i;c<2?m<s||(p a+[m];exit):(1+m...c*s).map{|k|f[s/(1-s/k),c-1,a+[k]]}}
f[gets.to_r/4,3,[]]

Код використовує мінімальні межі для кожної змінної, наприклад n/4<x<3n/4, аналогічно для y. Навіть останній приклад повертається миттєво (спробуйте тут ).

Приклади:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Холодне рішення, проте межі трохи жорсткі, тому що ваша програма на 1 000 000 знаходить більше рішення (див. Мій приклад).
Сомній

1
@ user2992539 Мій код повертає лексикографічно перше рішення (250001 <500000).
Говард

7

Mathematica 62

Цей звичайний ванільний розчин працює чудово - більшість часу.

f@n_ := FindInstance[4/n == 1/x + 1/y + 1/z && 0 < x < y < z, {x, y, z}, Integers]

Приклади та терміни (в секундах)

AbsoluteTiming[f[63]]
AbsoluteTiming[f[123]]
AbsoluteTiming[f[1003]]
AbsoluteTiming[f[3003]]
AbsoluteTiming[f[999999]]
AbsoluteTiming[f[1000000]]

{0.313671, {{x -> 16, y -> 1009, z -> 1017072}}}
{0.213965, {{x -> 31, y -> 3814, z -> 14542782}}}
{0.212016, {{x -> 251, у -> 251754, z -> 63379824762}}}
{0.431834, {{x -> 751, y -> 2255254, z -> 5086168349262}}}
{1.500332, {{x -> 250000, y - > 249999750052, z -> 1201920673328124750000}}}
{1.126821, {{x -> 375000, у -> 1125000, z -> 2250000}}}


Але це не є повноцінним рішенням. Є кілька цифр, які він не може вирішити. Наприклад,

AbsoluteTiming[f[30037]]
AbsoluteTiming[f[130037]]

{2.066699, FindInstance [4/30037 == 1 / x + 1 / y + 1 / z && 0 <x <y <z, {x, y, z}, цілі особи]}
{1.981802, FindInstance [4/130037 = = 1 / x + 1 / y + 1 / z && 0 <x <y <z, {x, y, z}, цілі особи]}


Правильний інструмент для правильної роботи. +1
Вільям Барбоса

3
@WilliamBarbosa Я б заперечував, що FindInstanceце не правильний інструмент, оскільки він не може гарантувати результат ...
Howard

2
@Howard Я говорив про Mathematica, власне
Вільям Барбоса

Reduceздається, вирішує вперті справи, хоча це часто потребує часу. Наприклад, 15 хвилин, щоб знайти 82 рішення для n = 10037.
DavidC

3

C #

Відмова від відповідальності: це не серйозна відповідь

Це просто підтримує всі можливості від 1 до 1 << 30. Це величезне, це повільно, я навіть не знаю, чи працює він правильно, але це відповідає технічним умовам буквально, оскільки він перевіряє стан щоразу, так що це приємно. Я не перевіряв цього, оскільки ideone має 5-секундний часовий обмеження для програм, і тому це не завершить виконання.

(Якщо хтось цікавився: це колосальні 308 байт )

static double[]f(double n)
{
    for(double x=1;x<1<<30;x++)
    {
        for(double y=1;y<1<<30;y++)
        {
            for(double z=1;z<1<<30;z++)
            {
                if(4/n==1/x+1/y+1/z)
                    return new[]{x,y,z};
            }
        }
    }
    return null;
}

Оновлення: виправлено це, щоб воно фактично працювало


2
Не працює (натяк: ціле ділення).
Говард

Ймовірно, це не спрацює через помилки округлення.
Somnium

@ user2992539 це працює для мене, я перевірив його 5як введення, і це дало правильний результат ( 2, 4, 20)
Крістоф Бьомвальдер,

@HackerCow може не працювати для великих цілих чисел.
Сомній

1
@HackerCow ви, звичайно, можете заощадити час, починаючи з y = x + 1 і z = y + 1. Можливо, буде швидше використовувати еквівалентний чек 4xyz = n (xy + yz + xz), хоча я погоджуюсь, що це більш тривалий вираз і також має проблеми із округленням.
Алхімік

3

Пітон 2 , 171 байт

from sympy import*
def f(n):
 for d in xrange(1,n*n):
  for p in divisors(4*d+n*n):
   q=(4*d+n*n)/p;x=(n+p)/4;y=(n+q)/4
   if (n+p)%4+(n+q)%4+n*x*y%d<1:return x,y,n*x*y/d

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

Перша відповідь досить швидко, щоб бути вичерпно перевіреною. Це може знайти рішення для всіх 3 ≤ п ≤ 1000000 приблизно 24 хвилин в цілому , в протягом в середньому близько 1,4 мілісекунд кожен.

Як це працює

Перепишіть 4 / n = 1 / x + 1 / y + 1 / z як z = n · x · y / d , де d = 4 · x · y - n · x - n · y . Тоді ми можемо множити 4 · d + n 2 = (4 · x - n ) · (4 · y - x < y < z , ми можемо принаймні довести d <3 · n n ), що дає нам набагато швидший спосіб пошуку x, а y тих пір, як d малий. Дано 2 /4 (отже, межа зовнішнього циклу), хоча на практиці вона має тенденцію бути набагато менше-95% часу, ми можемо використовувати д = 1, 2 або 3. Найгірший випадок - n = 769129, для якого найменший d - 1754 (цей випадок займає близько 1 секунди).


1

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

f[n_]:=(x=1;(w=While)[1>0,y=1;w[y<=x,z=1;w[z<=y,If[4/n==1/x+1/y+1/z,Return@{x,y,z}];++z];++y];++x])

Це досить наївна груба сила, тож насправді це не так добре. Я обов'язково дістанусь до мільйона (тому сміливо вважаю цього недійсним на даний момент). n = 100займає півсекунди, але n = 300вже займає 12 секунд.


1

Гольфлуа 75

Читає nз підказки (після виклику в терміналі), але в основному вона повторюється, як це робить рішення Хобі Кальвіна :

n=I.r()z=1@1~@y=1,z-1~@x=1,y-1?4*x*y*z==n*(y*z+x*z+x*y)w(n,x,y,z)~$$$z=z+1$

Неперевершена версія Луа вищезазначеного є

n=io.read()
z=1
while 1 do
   for y=1,z-1 do
      for x=1,y-1 do
         if 4*x*y*z==n*(y*z+x*z+x*y) then
            print(n,x,y,z)
            return
         end
      end
   end
   z=z+1
end

Приклади:

n=6     -->     3      4     12
n=12    -->     6     10     15
n=100   -->    60     75    100
n=1600  -->  1176   1200   1225

1

Пітона, 117

n=input();r=range;z=0
while 1:
 z+=1
 for y in r(z):
  for x in r(y):
    if 4*x*y*z==n*(y*z+x*z+x*y):print x,y,z;exit()

Приклад:

16 --> 10 12 15

Нічого занадто особливого.


1
Чому ви визначаєте функцію, якщо ви збираєтесь її зателефонувати лише один раз?
isaacg

@isaacg Це потрібно якось зупинити, але використання exit()натомість скорочує його.
Захоплення Кальвіна

0

C # - 134

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

Він обчислює всі приклади технічно правильно (останні два я не пробував, тому що, знову ж таки, ideone примушує 5-секундний обмеження), але перші дають правильний результат (не обов'язково результат, який ви обчислили, а правильний). Це дивно виводить номер з ладу (я поняття не маю , чому) , і це дає 10, 5, 2для 5(що є правильною відповіддю , згідно вікіпедії).

На даний момент 134 байти, я, мабуть, міг би розіграти його трохи більше.

float[]f(float n){float x=1,y,z;for(;x<1<<30;x++)for(y=1;y<x;y++)for(z=1;z<y;z++)if(4/n==1/x+1/y+1/z)return new[]{x,y,z};return null;}

0

Haskell - 150 символів

main = getLine >>= \n -> (return $ head $ [(x,y,z) | x <- [1..y], y <- [1..z], z <- [1..], (4/n') == (1/x) + (1/y) + (1/z)]) where n' = read n

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

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