Celem tego wyzwania jest zastosowanie metody Eulera do przybliżenia rozwiązania równania różniczkowego postaci f (n) (x) = c. †
Dane wejściowe będą listą liczb całkowitych, w których n- ta wartość reprezentuje wartość f (n) (0). Pierwsza liczba całkowita to f (0), druga to f '(0) i tak dalej. Ostatnia liczba całkowita na tej liście jest stała i zawsze pozostanie taka sama.
Jako dane wejściowe zostanie również podana dodatnia (niezerowa) liczba całkowita x , która reprezentuje wartość docelową (próbujesz oszacować f (x)). Rozmiar kroku dla metody Eulera będzie zawsze wynosił 1. W związku z tym konieczne będzie wykonanie sumy x kroków.
Jeśli nie jesteś zaznajomiony z metodą Eulera, oto szczegółowy przykład z objaśnieniem wprowadzonych danych [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
Zasadniczo każda komórka w wygenerowanej tabeli jest sumą komórki nad nią i komórki nad i po prawej stronie. Zatem f (a) = f (a-1) + f '(a-1); f '(a) = f' (a-1) + f '' (a-1); oraz f '' (a) = f '' (a-1) + f '' (a-1). Ostateczna odpowiedź to f (8) ≈ -8. ††
Lista wejściowa zawsze będzie zawierać 2 lub więcej elementów, z których wszystkie będą miały wartości bezwzględne mniejsze niż 10. x ≥ 1 jest również zagwarantowane. Dane wyjściowe to jedna liczba całkowita, przybliżenie f (x). Dane wejściowe można przyjmować w dowolnej kolejności (lista przed x lub x przed listą). W razie potrzeby x może być pierwszym lub ostatnim elementem listy.
Przypadki testowe:
[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
†: warto zauważyć, że zastosowanie metody przybliżenia w tej sytuacji jest w rzeczywistości głupie. jednak dla celów tego wyzwania wybrano najprostszą możliwą funkcję.
††: rzeczywista wartość wynosi -25⅓, co kwalifikowałoby to przybliżenie jako „niezbyt dobre”.
źródło
Odpowiedzi:
Haskell , 38 bajtów
Wypróbuj online!
Poprawiono z 39 bajtów:
Rekurencyjnie wyraża wynik
l%n
. Przesunięcie w górę odpowiada zmniejszeniun
, a przesunięcie w prawo odpowiadatail l
przesunięciu wszystkich elementów listy o jedno miejsce w lewo. Tak więc, wynikl%n
jest wartością powyżejl%(n-1)
, plus wartość powyżej i po prawej stronie(tail l)%(n-1)
Podstawowym przypadkiem
n==0
jest pobranie pierwszego elementu listy.Idealnie byłoby, gdyby dane wejściowe były wypełnione nieskończenie wieloma zerami po prawej stronie, ponieważ pochodne wielomianu ostatecznie stają się zerowe. Symulujemy to, dodając,
0
kiedy wykonujemytail
.Weird alt 41:
źródło
MATL , 9 bajtów
Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie
źródło
Galaretka ,
65 bajtówWypróbuj online!
-1 bajt dzięki @Doorknob
Wyjaśnienie
źródło
Brachylog ,
1312 bajtówWypróbuj online!
Jak to działa
Poprzednie 13-bajtowe rozwiązanie
Wypróbuj online!
Jak to działa
źródło
Mathematica, 32 bajty
źródło
Python ,
8058 bajtówUwielbiam matematykę dla tego wyzwania.
Jak to działa (działa tylko z Pythonem 2):
Wypróbuj online!
100 bajtów na przemian z użyciem trójkąta paskalowego
Jak to działa (działa dla Pythona 2 i 3):
Wzór ten działa poprzez mapowanie współczynniki szeregu
x
w paskalach trójkąta na tablicy. Każdy element trójkąta paskalnego jest określony przez funkcję wyboru wiersza i indeksu. Suma tej nowej tablicy jest równa wartości wyjściowej wx
. Jest również intuicyjny, ponieważ iterowany proces metody newtonów (pokazany w przykładzie) działa dokładnie tak, jak konstrukcja trójkąta paskalowego.Wypróbuj online!
Ogromne podziękowania dla ovs za zmniejszenie 22 bajtów poprzez przekształcenie pętli w funkcję rekurencyjną
źródło
Haskell,
5245 bajtówPrzykład użycia:
[-3,3,-3,3,-3,3,-3,3,-3] # 15
->-9009
. Wypróbuj online!Jak to działa
Edycja: @xnor zapisał 7 bajtów. Dzięki!
źródło
zipWith(+)=<<tail.(++[0])
, tj. Naprawić listę wcześniej niż później.=<<
=<<
stosuje się w ramach funkcji i jest definiowana jako:(=<<) f g x = f (g x) x
. Tutaj używamy=<<
infix:(f =<< g) x
withf = zipWith(+)
ig = tail
, co przekłada się nazipWith(+) (tail x) x
.CJam , 12 bajtów
Wypróbuj online!
Wyjaśnienie
Kod bezpośrednio implementuje procedurę opisaną w wyzwaniu.
źródło
Pyth , 10 bajtów
Zestaw testowy.
Jak to działa
źródło
APL (Dyalog) , 29 bajtów
Wypróbuj online!
To jest rekurencyjny dfn, ale okazuje się, że jest zbyt gadatliwy. Gra w golfa w toku ...
źródło
Właściwie 7 bajtów
Wypróbuj online!
Jak to działa
źródło
Oktawa , 42 bajty
Definiuje to anonimową funkcję. Wypróbuj online!
Wyjaśnienie
Rozwiązanie można obliczyć przez wielokrotne zwijanie tablicy wejściowej i wynikowych tablic za pomocą
[1, 1]
. Ale splot dwukrotnie, trzykrotnie lub ... z[1, 1]
odpowiada splotowi raz z[1, 2 ,1]
, lub[1, 3, 3, 1]
, lub ...; to znaczy z rzędem trójkąta Pascala. Uzyskuje się to jako anty-przekątną macierzy rzędu Pascalax+1
.źródło
JavaScript (ES6), 41 bajtów
Port of @ xnor doskonałej odpowiedzi Haskell. Poprzednie 47-bajtowe rozwiązanie.
źródło
Python 3 z Numpy , 82 bajty
Podobna do mojej odpowiedzi MATL , ale przy użyciu splotu pełnowymiarowego, a zatem wynikiem jest
x
-ty wpis końcowej tablicy.Wypróbuj online!
źródło
Python , 51 bajtów
Wypróbuj online!
To jest mój port odpowiedzi Haskella .
źródło