约∫((e ^ x)/(x ^ x))dx


24

您将估计以下值:

在此处输入图片说明

您输入的内容在哪里I

规则

  • 您不得使用任何内置的积分功能。
  • 您不得使用任何内置的无限求和函数。
  • 您的代码必须在合理的时间内执行(在我的计算机上少于20秒)
  • 您可以假设输入大于0但小于您的语言的上限。
  • 它可以是任何形式的标准返回/输出。

您可以在Wolfram | Alpha(您可以通过将预期的输入与链接的查询连接来进行验证)。

例子

(让我们调用函数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您所用语言的最大值。我将其添加到问题中。
Addison Crump

沃尔夫勒姆·阿尔法(Wolfram Alpha)说,最后一轮进入5.92228
尼尔

@Neil oo好吧,一定是输错了。谢谢!
Addison Crump

7
我将奖励200 rep到TI-BASIC中最短的有效答案,该答案将在20秒内以100%的速度在WabbitEmu上执行。
lirtosiast '16

@lirtosiast如果您仍打算跟进此赏金,则应在此处张贴。
Addison Crump

Answers:


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的图):

数学图

由于对于输入大于约9的函数,该函数求值几乎为0,因此,如果I小于9,则将输入截断为I,否则将其截断为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

感谢Dennis,节省了39个字节!


这还不等于:$ \ frac {t \ sum_ {k = 0} ^ {n}(f(a + kt)+ f(a +(k + 1)t)){2} $?使用算法似乎稍微简单一些。
Addison Crump

10^4可以写成1e4
Rainer P.

@VoteToClose最终采取了不同的方法
Alex A.

@RainerP。嘿,对。谢谢。
Alex A.

积分的渐近值为$ 6.39981 ... $。首先在$ I = 7.91399 ... $处获得$ 6.39981 ...-10 ^ {-4} $的值,因此您可以将$ 8 $而不是$ 9 $截断以节省一些时间。
埃里克·塔

9

果冻,20 19 17字节

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

这从@AlexA。的答案中借用了9个技巧的巧妙截断,并使用正确的黎曼和来估计相应的积分。

截断的测试用例需要一些时间,但是在网上尝试的速度足够快

怎么运行的

ð«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 Calculus类中如何引用它。:P Coolio。
Addison Crump

我不熟悉该名称,但是左手规则可能使用左端点。我的代码使用正确的代码。
丹尼斯

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达到Infinity:

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

2

golflua,83个字符

我承认:花了我一段时间才弄清楚了min(I,9)Alex提出的技巧,该技巧允许计算任意高的数字,因为那时整数已经收敛。

\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)

没有高尔夫的Lua等效于

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分钟。那完全是因为我实际上没有阅读Alex解释它的注释,只是在代码中看到了它。
凯尔·坎诺斯

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

天色已经晚了,我需要睡觉了,我看看明天能不能再来。

编辑:在看到@DenkerAffe的方法后设法使其缩短了很多时间。


1
我喜欢那里的话$ h * t。:D
Addison Crump

2

Pyth,34个 29字节

在@Dennis的帮助下节省了5个字节!

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
丹尼斯

@丹尼斯谢谢,没有想到这一点。排序技巧也很好,我只是在搜索min^^
Denker

2

MATL,26字节

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

这将积分近似为黎曼和。正如亚历克斯(Alex)所说,我们可以将积分间隔截断为大约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

Vitsy,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向您显示了结果。

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.