Орієнтовна ∫ ((e ^ x) / (x ^ x)) dx


24

Ви повинні наблизити значення:

введіть тут опис зображення

Де ваш внесок I.

Правила

  • Ви не можете використовувати будь-які вбудовані цілісні функції.
  • Ви не можете використовувати будь-які вбудовані функції нескінченного підсумовування.
  • Ваш код повинен виконуватись за розумну кількість часу (<20 секунд на моїй машині)
  • Ви можете припустити, що введення більше 0, але менше верхньої межі вашої мови.
  • Це може бути будь-яка форма стандартного повернення / виведення.

Ви можете підтвердити свої результати в Wolfram | Альфа (ви можете перевірити, з'єднавши призначений вхід із пов'язаним запитом).

Приклади

(назвемо функцію f)

f(1) -> 2.18273
f(50) -> 6.39981
f(10000) -> 6.39981
f(2.71828) -> 5.58040
f(3.14159) -> 5.92228

Ваша відповідь повинна бути точною ±.0001.


@ThomasKwa Максимум для вашої мови. Я додам це питання.
Аддісон Кримп

Вольфрам Альфа каже, що останній раунд5.92228
Ніл

@Neil oo Добре, тоді, мабуть, помилково введено помилку. Спасибі!
Аддісон Кримп

7
Я присуджую 200 реп. За найкоротший дійсний відповідь у TI-BASIC, який виконує за WabbitEmu за <20 секунд зі 100% швидкістю.
lirtosiast

@lirtosiast Якщо ви все ще маєте намір слідкувати за цією виграшею, ви повинні розмістити її тут .
Addison Crump

Відповіді:


10

Джулія, 79 77 38 байт

I->sum(x->(e/x)^x,0:1e-5:min(I,9))/1e5

Це анонімна функція, яка приймає числове значення і повертає поплавок. Щоб викликати його, призначте його змінній.

Підхід тут полягає у використанні правильної суми Рімана для наближення інтеграла, що задається наступною формулою:

латекс

У нашому випадку a = 0 і b = I , вхід. Ділимо область інтеграції на n = 10 5 дискретних ділянок, тому ∆ x = 1 / n = 10 -5 . Оскільки це константа відносно суми, ми можемо витягнути це за межі суми та просто підсумовувати оцінки функцій у кожній точці та ділити на n .

Функція напрочуд добре поводиться (сюжет від Mathematica):

mathematicaplot

Оскільки функція оцінює майже до 0 для входів більше 9, ми врізаємо вхід I, якщо я менше 9, або 9 в іншому випадку. Це спрощує розрахунки, які ми маємо значно зробити.

Невикористаний код:

function g(I)
    # Define the range over which to sum. We truncate the input
    # at 9 and subdivide the region into 1e5 pieces.
    range = 0:1e-5:min(I,9)

    # Evaluate the function at each of the 1e5 points, sum the
    # results, and divide by the number of points.
    return sum(x -> (e / x)^x, range) / 1e5
end

Збережено 39 байт завдяки Деннісу!


Хіба це не еквівалентно: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Це здається трохи простішим у використанні алгоритму.
Аддісон Крим

10^4можна записати як 1e4.
Райнер П.

@VoteToClose Закінчився з іншим підходом
Alex A.

@RainerP. Хе, правда. Спасибі.
Алекс А.

Асимптотичне значення інтеграла становить $ 6,39981 ... $. Значення $ 6.39981 ... - 10 ^ {- 4} $ спочатку досягається при $ I = 7.91399 ... $, тому ви можете скоротити $ 8 $ замість $ 9 $, щоб заощадити трохи часу.
Eric Towers

9

Желе, 20 19 17 байт

ð«9×R÷øȷ5µØe÷*×ḢS

Це запозичує розумний уріз на 9 трюку з відповіді @ AlexA. , і використовує правильну суму Рімана для оцінки відповідного інтеграла.

Урізані тестові справи займають певний час, але досить швидко спробуйте його онлайн!

Як це працює

ð«9×R÷øȷ5µØe÷*×ḢS  Main link. Input: I

      øȷ5          Niladic chain. Yields 1e5 = 100,000.

ð                  Dyadic chain. Left argument: I. Right argument: 1e5.
 «9                Compute min(I, 9).
   ×               Multiply the minimum with 1e5.
    R              Range; yield [1, 2, ..., min(I, 9) * 1e5] or [0] if I < 1e-5.
     ÷             Divide the range's items by 1e5.
                   This yields r := [1e-5, 2e-5, ... min(I, 9)] or [0] if I < 1e-5.

         µ         Monadic chain. Argument: r
          Øe÷      Divide e by each element of r.
             *     Elevate the resulting quotients to the corresponding elements,
                   mapping t -> (e/t) ** t over r.
                   For the special case of r = [0], this yields [1], since
                   (e/0) ** 0 = inf ** 0 = 1 in Jelly.
              ×Ḣ   Multiply each power by the first element of r, i.e., 1e-5 or 0.
                S  Add the resulting products.

О, гаразд. Ліве правило - це те, як воно позначається в класах обчислення AP. : P Coolio.
Аддісон Кримп

Я не знайомий з цією назвою, але ліве правило, ймовірно, використовує ліві кінцеві точки. Мій код використовує правильні.
Денніс

2
(~ -.-) ~ Це якась форма переданого правила. xD
Addison Crump

4

ES7, 78 байт

i=>[...Array(n=2e3)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i>9?i=9:0,i/=n,j=-i/2)*i

Для цього використовується правило прямокутника з 2000 прямокутниками, які (принаймні для прикладів), здається, дають досить точну відповідь, але точність може бути легко підвищена при необхідності. Доводиться використовувати трюк 9, інакше точність знижується для великих значень.

73-байтна версія, яка використовує прямокутники шириною ~ 0,001, тому вона не працює вище ~ 700, оскільки Math.exp вражає нескінченність:

i=>[...Array(n=i*1e3|0)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i/=n,j=-i/2)*i

2

гольфлуа , 83 чари

Я визнаю це: мені знадобилося певний час, щоб з'ясувати min(I,9)хитрість, яку Алекс представив, дозволяв обчислювати довільно високі числа, оскільки інтеграл до цього часу сходився.

\f(x)~M.e(x)/x^x$b=M.mn(I.r(),9)n=1e6t=b/n g=0.5+f(b/2)~@k=1,n-1g=g+f(k*t)$I.w(t*g)

Еквівалент Луа був би безгольовим

function f(x)
   return math.exp(x)/x^x
end

b=math.min(io.read("*n"),9)
n=1e6
t=b/n
g=0.5+f(b/2)

for k=1,n-1 do
   g=g+f(k*t)
end
io.write(t*g)

І під "часом" я маю на увазі близько 10 хвилин. І це було цілком, тому що я насправді не прочитав коментар Алекса, який пояснює це, просто побачив це в коді.
Кайл Канос

2

Python 2, 94 76 байт

Дякую @Dennis, що врятував мені 18 байт!

lambda I,x=1e5:sum((2.71828/i*x)**(i/x)/x for i in range(1,int(min(I,9)*x)))

Спробуйте в Інтернеті за допомогою тестів!

Використання методу прямокутника для наближення. Використовуючи прямокутник шириною 0,0001, що дає мені потрібну точність. Також обрізання входів більше 9, щоб запобігти помилкам пам'яті з дуже великими входами.


2

Perl 6, 90 55 байт

{my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

використання

my &f = {my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

f(1).say;       # 2.1827350239231
f(50).say;      # 6.39979602775846
f(10000).say;   # 6.39979602775846
f(2.71828).say; # 5.58039854392816
f(3.14159).say; # 5.92227602782184

Пізно, і мені потрібно спати, я побачу, чи зможу завтра коротше.

EDIT: Вдалося отримати його трохи коротше, побачивши метод @DenkerAffe.


1
Мені подобається, як там написано $ h * t. : D
Аддісон Кримп

2

Pyth, 34 29 байт

Збережено 5 байт за допомогою довідки @Dennis!

J^T5smcc^.n1d^ddJmcdJU*hS,Q9J

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

Пояснення

Той самий алгоритм, як і у моїй відповіді Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = вхід
J ^ T5 # встановити J так ширину прямокутника * 10 ^ 5
                       hS, Q9 # обрізати входи більше 9
                 mcdJU / J # діапазон від нуля до введення в J кроках
     mcc ^ .n1d ^ ddJ # обчислити площу для кожного елемента у списку
    s # Підсумуйте всі області та отриманий результат


Ви можете зберегти кілька байт, призначаючи Jдля ^T5і заміни множення з розподілом J. Також обрізання можна зробити за допомогою hS,Q9.
Денніс

@Dennis Спасибі, не думав про це. Також приємний сортувальний трюк, я просто шукав min^^
Денкер

2

MATL , 26 байт

9hX<t1e6XK:K/*ttZebb^/sK/*

Це наближає інтеграл як суму Рімана. Як стверджував Алекс, ми можемо скоротити інтервал інтеграції приблизно в 9, оскільки значення функцій дуже мало.

Максимальне значення функції менше 3, тому для отримання бажаної точності має бути достатньо кроку приблизно 1e-5. Отже, для максимального введення 9 нам потрібно близько 1e6 балів.

Це вимагає приблизно 1,5 секунди в онлайн-компіляторі для будь-якого вхідного значення.

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

9hX<         % input number, and limit to 9
t            % duplicate
1e6XK:       % generate vector [1,2,...,1e6]. Copy 1e6 to clipboard K
K/*          % divide by 1e6 and multiply by truncated input. This gives 
             % a vector with 1e6 values of x from 0 to truncated input
ttZe         % duplicate twice. Compute exp(x)
bb^          % rotate top three elements of stack twice. Compute x^x
/            % divide to compute exp(x)/x^x
s            % sum function values
K/*          % multiply by the step, which is the truncated input divided
             % by 1e6

2

Віци, 39 байт

Думав, що я можу також дати власний внесок. ¯ \ _ (ツ) _ / ¯ Для цього використовується оцінка лівої Ріманової суми інтегралів.

D9/([X9]1a5^D{/V}*0v1{\[EvV+DDv{/}^+]V*

D9/([X9]               Truncation trick from Alex A.'s answer.
D                      Duplicate input.
 9/                    Divide it by 9.
   ([  ]               If the result is greater than 0
     X9                Remove the top item of the stack, and push 9.

1a5^D{/V}*0v0{         Setting up for the summation.
1                      Push 1.
 a5^                   Push 100000.
    D                  Duplicate the top item of the stack.
     {                 Push the top item of the stack to the back.
      /                Divide the top two items of the stack. (1/100000)
       V               Save it as a global variable.
                       Our global variable is ∆x.
        }              Push the bottom item of the stack to the top.
         *             Multiply the top two items.
                       input*100000 is now on the stack.
          0v           Save 0 as a temporary variable.
            0          Push 1.
             {         Push the bottom item of the stack to the top.
                       input*100000 is now the top of the stack.

\[EvV+DDv{/}^+]        Summation.
\[            ]        Loop over this top item of the stack times.
                       input*100000 times, to be exact.
  E                    Push Math.E to the stack.
   v                   Push the temporary variable to the stack.
                       This is the current value of x.
    V+                 Add ∆x.
      DD               Duplicate twice.
        v              Save the temporary variable again.
         {             Push the top item of the stack to the back.
          /            Divide the top two items.
                       e/x
           }           Push the top item back to the top of the stack.
            ^          Put the second to top item of the stack to the power of the top item.
                       (e/x)^x
             +         Add that to the current sum.

V*                     Multiply by ∆x

Це залишає суму у верхній частині стека. Спробуйте це онлайн-посилання нижче, Nв кінці, щоб показати вам результат.

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

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