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


24

Você deve aproximar o valor de:

insira a descrição da imagem aqui

Onde está sua entrada I.

Regras

  • Você não pode usar nenhuma função integral incorporada.
  • Você não pode usar nenhuma função de soma infinita interna.
  • Seu código deve ser executado em um período de tempo razoável (<20 segundos na minha máquina)
  • Você pode assumir que a entrada é maior que 0, mas menor que o limite superior do seu idioma.
  • Pode ser qualquer forma de retorno / saída padrão.

Você pode verificar seus resultados em Wolfram | Alfa (você pode verificar concatenando a entrada pretendida para a consulta vinculada).

Exemplos

(vamos chamar a função f)

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

Sua resposta deve ser precisa ±.0001.


@ThomasKwa Máximo para o seu idioma. Vou adicioná-lo à pergunta.
Addison Crump

Wolfram Alpha diz que a última volta para5.92228
Neil

Tudo bem então, deve ter digitado errado. Obrigado!
Addison Crump #

7
Atribuirei 200 repetições à resposta mais curta válida no TI-BASIC, que é executada em <20 segundos no WabbitEmu a 100% da velocidade.
lirtosiast

@lirtosiast Se você ainda deseja acompanhar essa recompensa, deve publicá-la aqui .
Addison Crump

Respostas:


10

Julia, 79 77 38 bytes

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

Esta é uma função anônima que aceita um valor numérico e retorna um valor flutuante. Para chamá-lo, atribua-o a uma variável.

A abordagem aqui é usar uma soma Riemann correta para aproximar a integral, que é dada pela seguinte fórmula:

látex

No nosso caso, a = 0 eb = I , a entrada. Dividimos a região de integração em n = 10 5 porções discretas, então ∆ x = 1 / n = 10 -5 . Como essa é uma constante relativa à soma, podemos extrair isso da soma e simplesmente somar as avaliações da função em cada ponto e dividir por n .

A função é surpreendentemente bem-comportada (enredo do Mathematica):

mathematicaplot

Como a função avalia quase 0 para entradas maiores que cerca de 9, truncamos a entrada a ser eu , se eu for inferior a 9, ou 9 contrário. Isso simplifica os cálculos que temos que fazer significativamente.

Código não destruído:

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

Economizou 39 bytes graças a Dennis!


Isso também não é equivalente a: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Parece um algoritmo um pouco mais simples de usar.
Addison Crump

10^4pode ser escrito como 1e4.
Rainer P.

@VoteToClose Acabou adotando uma abordagem diferente #
Alex A.

@RainerP. Heh, certo. Obrigado.
7286 Alex A. Alex

O valor assintótico da integral é $ 6,39981 ... $. O valor $ 6.39981 ... - 10 ^ {- 4} $ é obtido pela primeira vez em $ I = 7.91399 ... $, para que você possa truncar em $ 8 $ em vez de $ 9 $ para economizar um pouco de tempo.
Eric Towers

9

Geléia, 20 19 17 bytes

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

Isso pega emprestado o inteligente truncado às 9 da resposta de @ AlexA. E usa uma soma Riemann certa para estimar a integral correspondente.

Os casos de teste truncados demoram um pouco, mas são rápidos o suficiente no Experimente online!

Como funciona

ð«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.

Ah, tudo bem. A regra da esquerda é como é referida nas classes de cálculo AP. : P Coolio.
Addison Crump

Não conheço esse nome, mas a regra da esquerda provavelmente usa os pontos de extremidade esquerdos. Meu código usa os corretos.
Dennis

2
(~ -.-) ~ É alguma forma de regra de mão. xD
Addison Crump

4

ES7, 78 bytes

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

Isso usa a regra de retângulo com 2000 retângulos, que (pelo menos para os exemplos) parecem produzir uma resposta suficientemente precisa, mas a precisão pode ser facilmente aumentada, se necessário. Ele tem que usar o truque 9, caso contrário, a precisão cai para valores grandes.

Versão de 73 bytes que usa retângulos de largura ~ 0,001 para que não funcione acima de ~ 700 porque Math.exp atinge o Infinito:

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 caracteres

Admito: demorei um pouco para descobrir o min(I,9)truque que Alex apresentava, permitindo calcular números arbitrariamente altos porque a integral convergia até então.

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

Um equivalente Lua não-golfado seria

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)

E por "um tempo" quero dizer cerca de 10 minutos. E isso foi inteiramente porque eu realmente não li o comentário de Alex que explica isso, apenas o vi no código.
Kyle Kanos

2

Python 2, 94 76 bytes

Obrigado a @Dennis por me salvar 18 bytes!

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

Experimente online com casos de teste!

Usando o método retângulo para a aproximação. Usando uma largura de retângulo de 0,0001, obtendo a precisão exigida. Também trunca entradas maiores que 9 para evitar erros de memória com entradas muito grandes.


2

Perl 6, 90 55 bytes

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

uso

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

É tarde e eu preciso dormir, vou ver se posso diminuir isso amanhã.

EDIT: Conseguiu reduzi-lo um pouco depois de ver o método da @DenkerAffe.


11
Eu gosto de como diz $ h * t lá. : D
Addison Crump

2

Pitão, 34 29 bytes

Salvo 5 bytes com alguma ajuda de @Dennis!

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

Experimente online!

Explicação

O mesmo algoritmo da minha resposta em Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = entrada
J ^ T5 # define J, largura do retângulo * 10 ^ 5
                       Entradas truncadas hS, Q9 # maiores 9
                 mcdJU / J # variam de zero a entrada nas etapas J
     mcc ^ .n1d ^ ddJ # calcula a área para cada elemento da lista
    s # Soma todas as áreas e resultado da saída


Você pode economizar alguns bytes através da atribuição Jde ^T5e trocando multiplicação com divisão por J. Além disso, o truncamento pode ser feito com hS,Q9.
Dennis

@ Dennis Obrigado, não pensei nisso. Também o truque de classificação é bom, eu estava apenas procurando min^^
Denker

2

MATL , 26 bytes

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

Isso aproxima a integral como uma soma de Riemann. Como argumentado por Alex, podemos truncar o intervalo de integração em aproximadamente 9, porque os valores da função são muito pequenos além disso.

O valor máximo da função é menor que 3, portanto, uma etapa de cerca de 1e-5 deve ser suficiente para obter a precisão desejada. Portanto, para a entrada máxima 9, precisamos de cerca de 1e6 pontos.

Isso leva cerca de 1,5 segundos no compilador online, para qualquer valor de entrada.

Experimente online !

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 bytes

Pensei que também poderia dar minha própria contribuição. ¯ \ _ (ツ) _ / ¯ Utiliza a estimativa de integrais à esquerda de Riemann Sum.

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

Isso deixa a soma no topo da pilha. O link try it online abaixo tem Nno final para mostrar o resultado.

Experimente Online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.