ใช้วิธีของออยเลอร์


9

เป้าหมายของความท้าทายนี้คือการใช้วิธีการของออยเลอร์เพื่อประมาณวิธีแก้ปัญหาของสมการเชิงอนุพันธ์ของรูปแบบ f (n) (x) = c

อินพุตจะเป็นรายการของจำนวนเต็มซึ่งค่าn th แสดงถึงค่าของ f (n) (0) เลขจำนวนเต็มแรกคือ f (0) ตัวที่สองคือ f '(0) และอื่น ๆ จำนวนเต็มสุดท้ายในรายการนี้คือค่าคงที่และจะยังคงเหมือนเดิมเสมอ

นอกจากนี้ยังเป็น input จะเป็นบวก (ไม่ใช่ศูนย์) จำนวนเต็มxซึ่งหมายถึงค่าเป้าหมาย (คุณกำลังพยายามที่จะประเมิน f (x)) ขนาดขั้นตอนสำหรับวิธีของออยเลอร์จะเป็น 1 เสมอดังนั้นคุณจะต้องรวมxขั้นตอนทั้งหมด

หากคุณเป็น unfamliar ด้วยวิธีออยเลอร์นี่เป็นตัวอย่างที่มีคำอธิบายรายละเอียดสำหรับการป้อนข้อมูลที่[4, -5, 3, -1], x = 8

x       f(x)      f'(x)     f''(x)    f'''(x)
0          4         -5          3         -1
1   4-5 = -1  -5+3 = -2   3-1 =  2         -1
2  -1-2 = -3  -2+2 =  0   2-1 =  1         -1
3  -3+0 = -3   0+1 =  1   1-1 =  0         -1
4  -3+1 = -2   1+0 =  1   0-1 = -1         -1
5  -2+1 = -1   1-1 =  0  -1-1 = -2         -1
6  -1+0 = -1   0-2 = -2  -2-1 = -3         -1
7  -1-2 = -3  -2-3 = -5  -3-1 = -4         -1
8  -3-5 = -8

โดยพื้นฐานแล้วเซลล์แต่ละเซลล์ในตารางที่สร้างขึ้นคือผลรวมของเซลล์ด้านบนและเซลล์ด้านบนและด้านขวา ดังนั้น f (a) = f (a-1) + f '(a-1); f '(a) = f' (a-1) + f '' (a-1); และ f '' (a) = f '' (a-1) + f '' '(a-1) คำตอบสุดท้ายคือ f (8) ≈ -8 ††

รายการอินพุตจะมีองค์ประกอบตั้งแต่ 2 องค์ประกอบขึ้นไปซึ่งทั้งหมดจะมีค่าสัมบูรณ์น้อยกว่า 10 x ≥ 1 รับประกัน เอาท์พุทเป็นจำนวนเต็มเดียวการประมาณ f (x) อินพุตอาจถูกใช้ตามลำดับใด ๆ (รายการก่อนxหรือxก่อนรายการ) xอาจเป็นองค์ประกอบแรกหรือสุดท้ายของรายการหากต้องการ

กรณีทดสอบ:

[4, -5, 3, -1], x = 8 => -8
[1, 2, 3, 4, 5, 6], x = 10 => 3198
[1, 3, 3, 7], x = 20 => 8611
[-3, 3, -3, 3, -3, 3, -3, 3, -3], x = 15 => -9009
[1, 1], x = 1 => 2

†: เป็นที่น่าสังเกตว่าการใช้วิธีการประมาณค่าในสถานการณ์นี้คืออันที่จริงแล้วโง่ อย่างไรก็ตามฟังก์ชั่นที่ง่ายที่สุดที่เป็นไปได้นั้นถูกเลือกเพื่อความท้าทาย

††: ค่าจริงเกิดขึ้นที่-25⅓ซึ่งจะถือว่าการประมาณนี้เป็น "ไม่ดีมาก"



คำตอบ:


3

Haskell , 38 ไบต์

l%n|n<1=l!!0|m<-n-1=l%m+tail(l++[0])%m

ลองออนไลน์!

ปรับปรุงจาก 39 ไบต์:

l%0=l!!0
l%n=l%(n-1)+tail(l++[0])%(n-1)

l%nซ้ำเป็นการแสดงออกถึงการส่งออก การเลื่อนขึ้นสอดคล้องกับการลดลงnและการเลื่อนไปทางขวาสอดคล้องกับการtail lเลื่อนรายการองค์ประกอบทั้งหมดไปทางซ้ายหนึ่งช่องว่าง ดังนั้นผลลัพธ์l%nคือค่าด้านบนl%(n-1)บวกกับค่าด้านบนและทางขวา(tail l)%(n-1)

กรณีฐานn==0คือการใช้องค์ประกอบรายการแรก

โดยอุดมคติแล้วอินพุตจะถูกเติมด้วยเลขศูนย์ทางด้านขวาจำนวนนับไม่ถ้วนเนื่องจากอนุพันธ์ของพหุนามกลายเป็นศูนย์ในที่สุด เราจำลองนี้โดยท้ายเมื่อเราใช้เวลา0tail

แปลก ๆ alt 41:

(iterate(\q l->q l+q(tail l++[0]))head!!)


3

เยลลี่ , 6 5 ไบต์

Ḋ+$¡Ḣ

ลองออนไลน์!

-1 ไบต์ขอบคุณ @Doorknob

คำอธิบาย

Ḋ+$¡Ḣ  - Main dyadic link. First input list, second x
       - (implicit) on the previous iteration (starting at input list)
Ḋ      - Dequeue. e.g. [-5,3,-1]
 +     - Add this to
       - (implicit) the previous iteration. e.g. [4+(-5),-5+3,3+(-1),-1+0]
  $¡   - apply this successively x times
    Ḣ  - get the first element from the resultant list

3

Brachylog , 13 12 ไบต์

{,0s₂ᶠ+ᵐ}ⁱ⁾h

ลองออนไลน์!

มันทำงานอย่างไร

{,0s₂ᶠ+ᵐ}ⁱ⁾h
{       }ⁱ⁾   iterate the previous predicate
              to the array specified by first element of input
              as many times as the second element of input
           h  and get the first element

              example input to predicate: [4, _5, 3, _1]
 ,0           append 0: [4, _5, 3, _1, 0]
   s₂ᶠ        find all substrings with length 2:
              [[4, _5], [_5, 3], [3, _1], [_1, 0]]
      +ᵐ      "add all the elements" mapped to each subarray:
              [_1, _2, _2, _1]

โซลูชัน 13 ไบต์ก่อนหน้า

{b,0;?z+ᵐ}ⁱ⁾h

ลองออนไลน์!

มันทำงานอย่างไร

{b,0;?z+ᵐ}ⁱ⁾h
{        }ⁱ⁾   iterate the previous predicate
               to the array specified by first element of input
               as many times as the second element of input
            h  and get the first element

               example input to predicate: [4, _5, 3, _1]
 b             remove the first element: [_5, 3, _1]
  ,0           append 0: [_5, 3, _1, 0]
    ;?         pair with input: [[_5, 3, _1, 0], [4, _5, 3, _1]]
      z        zip: [[_5, 4], [3, _5], [_1, 3], [0, _1]]
       +ᵐ      "add all the elements" mapped to each subarray:
               [_1, _2, _2, _1]

2

Mathematica ขนาด 32 ไบต์

#&@@Nest[#+Rest@#~Append~0&,##]&
                               &  make a pure function
    Nest[                 &,##]   call inner function as many times as specified
           Rest@#                 drop the first element of the list
                 ~Append~0        and add a 0 to get [b,c,d,0]
         #+                       add original list to get [a+b,b+c,c+d,d]
#&@@                              take the first element after x iterations

2

งูหลาม , 80 58 ไบต์

รักคณิตศาสตร์สำหรับความท้าทายนี้

f=lambda a,x:x and f(map(sum,zip(a,a[1:]+[0])),x-1)or a[0]

มันทำงานอย่างไร (ใช้ได้กับ python 2 เท่านั้น):

f=lambda a,x:                                              - new lambda function
             x and                                         - iterate itself x times
                     map(sum,zip(a,a[1:]+[0]))             - e.g; f(a) = f(a-1) + f'(a-1)
                   f(                         ,x-1)        - iterate new array into itself
                                                   or a[0] - return first element

ลองออนไลน์!

100 ไบต์สลับกับการใช้รูปสามเหลี่ยมปาสกาล

from math import factorial as F
f=lambda a,x:sum([(a+[0]*x)[i]*F(x)/(F(x-i)*F(i))for i in range(x)])

มันทำงานอย่างไร (ใช้ได้กับหลาม 2 และ 3):

sum([                                                ]) - take the sum of array
     (a+[0]*x)                                        - append x zeros
              [i]*F(x)/(F(x-i)*F(i))                  - multiply each element by x choose i
                                    for i in range(x) - do this for every element

สูตรนี้ทำงานโดยการแมปค่าสัมประสิทธิ์ของแถวxของPascals สามเหลี่ยมลงในอาร์เรย์ องค์ประกอบของสามเหลี่ยมปาสคาลแต่ละอันจะถูกกำหนดโดยฟังก์ชั่นเลือกของแถวและดัชนี xผลรวมของแถวใหม่นี้จะเทียบเท่ากับการส่งออกที่ นอกจากนี้ยังใช้งานง่ายเนื่องจากกระบวนการวนซ้ำของวิธีการนิวตัน (แสดงในตัวอย่าง) ทำหน้าที่เหมือนกับการสร้างสามเหลี่ยมปาสคาล

ลองออนไลน์!

ขอบคุณมากสำหรับovsสำหรับการลด 22 ไบต์ด้วยการแปลงลูปเป็นฟังก์ชันแบบเรียกซ้ำ


นี่คือรุ่นที่ได้รับการปรับปรุง ผมแปลงสำหรับวงไปยังฟังก์ชันเวียน
OVS

Ah, @ovs ความคิดที่ดี
Graviton

ยิ่งสั้นลง โปรดทราบว่าจะใช้งานได้กับ python2 เท่านั้น
ovs

1

Haskell, 52 45 ไบต์

l#n=iterate(zipWith(+)=<<tail.(++[0]))l!!n!!0

ตัวอย่างการใช้งาน: ->[-3,3,-3,3,-3,3,-3,3,-3] # 15 ลองออนไลน์!-9009

มันทำงานอย่างไร

iterate(      )l          -- apply the function again and again starting with l
                          -- and collect the intermediate results in a list
                          -- the function is
          (++[0])         -- append a zero 
  zipWith(+)=<<tail       -- and build list of neighbor sums
                     !!0  -- take the first element from
                  !!n     -- the nth result

แก้ไข: @xnor บันทึก 7 ไบต์ ขอบคุณ!


ฉันคิดว่าฟังก์ชั่นที่ทำซ้ำอาจเป็นzipWith(+)=<<tail.(++[0])เช่นแก้ไขรายการล่วงหน้ามากกว่าหลังจากนั้น
xnor

@xnor: ใช่นั่นจะช่วยประหยัดจำนวนไบต์ ขอบคุณ!
nimi

ฉันไม่สามารถมัดใจของฉันรอบการใช้งานของ=<<ที่นี่นี้เป็นคนบ้า :)
flawr

@flawr: ถูกนำมาใช้ในบริบทการทำงานและมีการกำหนดเป็น:=<< (=<<) f g x = f (g x) xที่นี่เราใช้=<<มัด: (f =<< g) xด้วยf = zipWith(+)และซึ่งแปลg = tail zipWith(+) (tail x) x
nimi

ขอบคุณสำหรับคำอธิบายรายละเอียดฉันไม่ได้ตระหนักถึงฟังก์ชั่น monad!
ข้อบกพร่อง

1

CJam , 12 ไบต์

q~{_(;.+}*0=

ลองออนไลน์!

คำอธิบาย

รหัสนี้ใช้ขั้นตอนที่อธิบายไว้ในความท้าทายโดยตรง

q~            e# Read input and evaluate. Pushes the array and the number x
  {     }*    e# Do the following x times
   _          e# Duplicate array
    (;        e# Remove first element
      .+      e# Vectorized sum. The last element in the first array, which doesn't 
              e# have a corresponding entry in the second, will be left as is
          0=  e# Get first element. Implicitly display



1

ที่จริงแล้ว 7 ไบต์

;lr(♀█*

ลองออนไลน์!

มันทำงานอย่างไร

;lr(♀█*  input:
         8, [4, -5, 3, -1]
         top of stack at the right
;        duplicate
         8, [4, -5, 3, -1], [4, -5, 3, -1]
 l       length
         8, [4, -5, 3, -1], 4
  r      range
         8, [4, -5, 3, -1], [0, 1, 2, 3]
   (     rotate stack
         [4, -5, 3, -1], [0, 1, 2, 3], 8
    ♀█   map "n choose r"
         [4, -5, 3, -1], [1, 8, 28, 56]
      *  dot product
         -8

1

อ็อกเทฟ 42 ไบต์

@(a,x)conv(a,diag(flip(pascal(x+1))))(x+1)

สิ่งนี้นิยามฟังก์ชันที่ไม่ระบุชื่อ ลองออนไลน์!

คำอธิบาย

วิธีการแก้ปัญหาสามารถคำนวณได้โดยการโน้มน้าวอาร์เรย์อินพุตและอาร์เรย์ผลลัพธ์ด้วย[1, 1]ซ้ำ ๆ แต่การชักจูงสองครั้งหรือสามครั้งหรือ ... [1, 1]สอดคล้องกับการโน้มน้าวใจครั้งเดียวด้วย[1, 2 ,1]หรือ[1, 3, 3, 1]หรือ ... ; นั่นคือกับแถวของสามเหลี่ยมปาสคาล x+1นี้จะได้รับเป็นป้องกันเส้นทแยงมุมของเมทริกซ์ปาสกาลของการสั่งซื้อ


0

JavaScript (ES6), 41 ไบต์

f=(a,x,[b,...c]=a)=>x--?f(a,x)+f(c,x):b|0

คำตอบที่ยอดเยี่ยมของ Haskell ของ @xnor พอร์ต โซลูชัน 47 ไบต์ก่อนหน้า

f=(a,x)=>x--?f(a.map((e,i)=>e+~~a[i+1]),x):a[0]


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.