Xấp xỉ ((e ^ x) / (x ^ x)) dx


24

Bạn phải ước tính giá trị của:

nhập mô tả hình ảnh ở đây

Trường hợp đầu vào của bạn là I.

Quy tắc

  • Bạn không được sử dụng bất kỳ hàm tích hợp nào.
  • Bạn không được sử dụng bất kỳ hàm tổng kết vô hạn tích hợp nào.
  • Mã của bạn phải thực thi trong một khoảng thời gian hợp lý (<20 giây trên máy của tôi)
  • Bạn có thể cho rằng đầu vào lớn hơn 0 nhưng nhỏ hơn giới hạn trên của ngôn ngữ của bạn.
  • Nó có thể là bất kỳ hình thức trả lại / đầu ra tiêu chuẩn.

Bạn có thể xác minh kết quả của bạn tại Wolfram | Alpha (bạn có thể xác minh bằng cách ghép nối đầu vào dự định của bạn với truy vấn được liên kết).

Ví dụ

(hãy gọi hàm f)

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

Câu trả lời của bạn phải chính xác ±.0001.


@ThomasKwa Tối đa cho ngôn ngữ của bạn. Tôi sẽ thêm nó vào câu hỏi.
Addison Crump

Wolfram Alpha nói rằng vòng đấu cuối cùng sẽ diễn ra5.92228
Neil

@Neil oo Được rồi, chắc đã nhầm rồi. Cảm ơn!
Addison Crump

7
Tôi sẽ trao 200 đại diện cho câu trả lời hợp lệ ngắn nhất trong TI-BASIC thực hiện trong <20 giây trên WmusEmu với tốc độ 100%.
lirtosiast

@lirtosiast Nếu bạn vẫn có ý định theo dõi tiền thưởng này, bạn nên đăng nó ở đây để thay thế.
Addison Crump

Câu trả lời:


10

Julia, 79 77 38 byte

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

Đây là một hàm ẩn danh chấp nhận một giá trị số và trả về một số float. Để gọi nó, gán nó cho một biến.

Cách tiếp cận ở đây là sử dụng tổng Riemann đúng để tính gần đúng tích phân, được đưa ra theo công thức sau:

mủ cao su

Trong trường hợp của chúng tôi, a = 0 và b = I , đầu vào. Chúng tôi chia vùng tích hợp thành n = 10 5 phần riêng biệt, do đó ∆ x = 1 / n = 10 -5 . Vì đây là hằng số liên quan đến tổng, nên chúng ta có thể kéo giá trị này ra ngoài tổng và chỉ cần tính tổng các đánh giá hàm tại mỗi điểm và chia cho n .

Hàm này hoạt động tốt một cách đáng ngạc nhiên (cốt truyện từ Mathicala):

toán học

Vì hàm ước tính gần bằng 0 cho các đầu vào lớn hơn khoảng 9, nên chúng tôi cắt ngắn đầu vào thành I nếu tôi nhỏ hơn 9 hoặc 9 nếu không. Điều này đơn giản hóa các tính toán chúng ta phải làm đáng kể.

Mã bị đánh cắp:

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

Đã lưu 39 byte nhờ Dennis!


Điều này cũng không tương đương với: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Điều đó có vẻ hơi đơn giản của một thuật toán để sử dụng.
Addison Crump

10^4có thể được viết là 1e4.
Rainer P.

@VoteToClose Kết thúc bằng một cách tiếp cận khác
Alex A.

@RainerP. Heh, phải rồi. Cảm ơn.
Alex A.

Giá trị tiệm cận của tích phân là $ 6.39981 ... $. Giá trị $ 6.39981 ... - 10 ^ {- 4} $ lần đầu tiên đạt được tại $ I = 7.91399 ... $, vì vậy bạn có thể cắt ngắn ở mức $ 8 $ thay vì $ 9 $ để tiết kiệm một chút thời gian.
Tháp Eric

9

Thạch, 20 19 17 byte

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

Điều này mượn cách cắt ngắn thông minh ở 9 mẹo từ câu trả lời của @ AlexA. Và sử dụng tổng Riemann đúng để ước tính tích phân tương ứng.

Các trường hợp kiểm tra rút ngắn mất một thời gian, nhưng đủ nhanh trên Dùng thử trực tuyến!

Làm thế nào nó hoạt động

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

Ồ được rồi. Quy tắc bàn tay trái là cách nó được đề cập trong các lớp Tính toán AP. : P Coolio.
Addison Crump

Tôi không quen với tên đó, nhưng quy tắc bên trái có thể sử dụng các điểm cuối bên trái. Mã của tôi sử dụng đúng.
Dennis

2
(~ -.-) ~ Đó là một số hình thức của quy tắc bàn tay. xD
Addison Crump

4

ES7, 78 byte

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

Điều này sử dụng quy tắc hình chữ nhật với 2000 hình chữ nhật, mà (ít nhất là đối với các ví dụ) dường như tạo ra một câu trả lời đủ chính xác, nhưng độ chính xác có thể dễ dàng tăng lên nếu cần thiết. Nó phải sử dụng thủ thuật 9 nếu không độ chính xác giảm xuống cho các giá trị lớn.

Phiên bản 73 byte sử dụng hình chữ nhật có chiều rộng ~ 0,001 nên nó không hoạt động trên ~ 700 vì Math.bao đạt 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 ký tự

Tôi sẽ thừa nhận điều đó: phải mất một thời gian tôi mới tìm ra min(I,9)mánh khóe mà Alex đưa ra cho phép tính toán số lượng cao tùy ý vì tích phân hội tụ trước đó.

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

Một Lua không tương đương sẽ là

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)

Và bởi "một lúc" tôi có nghĩa là khoảng 10 phút. Và đó hoàn toàn là vì tôi đã không thực sự đọc bình luận của Alex giải thích nó, chỉ nhìn thấy nó trong mã.
Kyle Kanos 7/2/2016

2

Python 2, 94 76 byte

Cảm ơn @Dennis đã tiết kiệm cho tôi 18 byte!

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

Hãy thử trực tuyến với testcase!

Sử dụng phương pháp hình chữ nhật cho gần đúng. Sử dụng chiều rộng hình chữ nhật là 0,0001 mang lại cho tôi độ chính xác theo yêu cầu. Ngoài ra cắt ngắn đầu vào lớn hơn 9 để ngăn ngừa lỗi bộ nhớ với đầu vào rất lớn.


2

Perl 6, 90 55 byte

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

sử dụng

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

Trời đã khuya và tôi cần ngủ, tôi sẽ xem liệu tôi có thể có được thứ này ngắn hơn vào ngày mai không.

EDIT: Được quản lý để có được nó ngắn hơn một chút sau khi xem phương pháp của @DenkerAffe.


1
Tôi thích cách nó nói $ h * t trong đó. : D
Addison Crump

2

Pyth, 34 29 byte

Đã lưu 5 Byte với một số trợ giúp từ @Dennis!

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

Hãy thử trực tuyến!

Giải trình

Thuật toán tương tự như trong câu trả lời Python của tôi .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = đầu vào
J ^ T5 # đặt J sao cho chiều rộng hình chữ nhật * 10 ^ 5
                       hS, Q9 # cắt ngắn đầu vào lớn hơn 9
                 phạm vi mcdJU / J # từ 0 đến Input trong các bước J
     mcc ^ .n1d ^ ddJ # tính diện tích cho từng phần tử trong danh sách
    s # Tổng tất cả các khu vực và kết quả đầu ra


Bạn có thể tiết kiệm một vài byte bằng cách gán Jcho ^T5và trao đổi nhân với bộ phận bằng J. Ngoài ra, việc cắt ngắn có thể được thực hiện với hS,Q9.
Dennis

@Dennis Cảm ơn, đã không nghĩ về điều đó. Ngoài ra thủ thuật sắp xếp rất hay, tôi chỉ tìm kiếm min^^
Denker

2

MATL , 26 byte

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

Điều này gần đúng tích phân dưới dạng tổng Riemann. Theo lập luận của Alex, chúng ta có thể rút ngắn khoảng tích hợp ở mức xấp xỉ 9 vì các giá trị hàm rất nhỏ vượt quá.

Giá trị tối đa của hàm nhỏ hơn 3, vì vậy một bước khoảng 1e-5 phải đủ để đạt được độ chính xác mong muốn. Vì vậy, đối với đầu vào tối đa 9, chúng ta cần khoảng 1e6 điểm.

Điều này mất khoảng 1,5 giây trong trình biên dịch trực tuyến, cho bất kỳ giá trị đầu vào.

Hãy thử trực tuyến !

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 byte

Nghĩ rằng tôi cũng có thể đóng góp của riêng tôi. ¯ \ _ () _ / ¯ Điều này sử dụng ước lượng tích phân Riemann Sum bên tay trái.

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

Điều này để lại tổng trên đầu ngăn xếp. Liên kết thử trực tuyến dưới đây có Nkết thúc để cho bạn thấy kết quả.

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.