Wprowadzenie:
Sinus z x
wyraża się wzorem:
sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! // and more follows...
Cosinus z x
oblicza się według wzoru:
cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - x^10/10! // and more follows...
Zadanie:
Biorąc pod uwagę wartość x
i n
, napisz program (bez funkcji itp.), Aby wypisał wartość sin(x)
i cos(x)
poprawił upto n
warunki powyższej formuły. Załóżmy, że x
jest w radianach.
Wejście:
x n
Liczba dziesiętna x
(z maksymalnie 3 miejscami dziesiętnymi) i liczba całkowita n
. Dane wejściowe muszą być ustawione na standardowe wejście lub okno dialogowe z pytaniem (jeśli Twój język nie obsługuje standardowego wejścia)
Wynik:
[sin(x)]
[cos(x)]
Wartość obu sin(x)
i cos(x)
powinny być zaokrąglone do 6 miejsc po przecinku. Jeśli sin(x)
jest 0.5588558855
(10 cyfr dziesiętnych), należy je zaokrąglić do 0.558856
(6 cyfr dziesiętnych). Zaokrąglanie musi odbywać się do najbliższej, jak opisano w piątej kolumnie „Zaokrąglaj do najbliższej” tabeli w tym artykule Wiki .
Ograniczenia:
1 <= x <= 20
1 <= n <= 20
Próbki:
----
5 3
10.208333
14.541667
----
8.555 13
0.765431
-0.641092
----
9.26 10
-3.154677
-8.404354
----
6.54 12
0.253986
0.967147
----
5 1
5.000000
1.000000
----
20 20
-5364.411846
-10898.499385
----
Uwagi:
- Standardowe luki są zabronione.
- Wbudowane funkcje matematyczne i operatory trygonometrii (sin, cos, tan itp.), Silnia i potęgowanie nie mogą być używane. Możesz użyć wbudowanej funkcji zaokrąglania do oszacowania wyniku obliczeń
sin(x)
icos(x)
do 6-tej cyfry dziesiętnej. - Nie ma potrzeby obsługi niewłaściwych danych wejściowych.
- W programie można używać tylko znaków ASCII, a nie chińskich znaków Unicode, które umożliwiają kompresję kodu.
- Twój program musi zakończyć działanie i wyświetlić dane wyjściowe w ciągu 3 sekund od wejścia.
- Twoja odpowiedź musi towarzyszyć niepoddanemu kodowi wraz z objaśnieniem kodu (obowiązkowe, jeśli kod nie jest od razu oczywisty dla programistów, którzy nie znają Twojego języka, zwłaszcza GolfScript, J itp.).
- Podaj link do kompilatora online, w którym można przetestować Twój program.
Punktacja:
Odpowiedź z najniższą długością kodu w znakach, w tym spacjami, tabulatorami itp. Wygrywa! Zwycięzca zostanie ogłoszony 21 maja 2014 r.
EDYCJA : 21.05.14 Zwycięzca jest aditsu w języku CJam . Drugie miejsce następujące jpjacobs z językiem J , a po drugie drugie miejsce jest Primo z językiem Perl . Gratulacje dla wszystkich!
mod 2pi
operacji w celu przyspieszenia konwergencji danych wejściowych byłoby raczej przydatne - jest to jedna z wielu ulepszeń, z których korzysta świat rzeczywisty podczas obsługi tych funkcji. (właściwie mod pi i znak świadomości).Odpowiedzi:
CJam - 42
Wypróbuj online pod adresem http://cjam.aditsu.net
Wyjaśnienie:
r
odczytuje token z danych wejściowychd
konwertuje na podwójne:X
przypisania do zmiennej X;
wyskakuje wartość ze stosu1
umieszcza 1 na stosie (pierwszy termin)_
duplikuje 1r
czyta następny token (n)i
konwertuje na liczbę całkowitą2*,1>{...}/
jest rodzajem pętli z 1 do 2 * n - 1:-
2*
mnoży przez 2-
,
tworzy tablicę od 0 do (ostatnia wartość) -1-
1>
usuwa pierwszy element tablicy (0)-
{...}/
wykonuje blok dla każdego elementu w tablicy_
powiela pętlę „ zmienna "(nazwijmy to k)2%2*(
konwertuje z parzystej / nieparzystej na -1/1:-
2%
jest modulo 2 (-> 0/1)-
2*
mnoży przez 2 (-> 0/2)-
(
zmniejszenie (-> -1/1)*
mnoży się, zmieniając znak co drugi raz,/
dzieląc termin na stosie przez k lub -k; to jest „/ k!” część obliczeń wraz ze zmianą znakuX*
mnoży się przez X; jest to część obliczeń „X ^ k”; uzyskaliśmy kolejny termin z serii_
duplikatów termin, który będzie używany do obliczenia następnego terminu w następnej iteracji;
(po pętli) wyskakuje ostatni zduplikowany termin]
zbiera warunki na stosie w tablicyW tym momencie mamy tablicę [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] zawierające dokładnie wszystkie terminy, których potrzebujemy dla cos (x) i sin (x), przeplatane
2/
dzieli tę tablicę na paryz
transponuje macierz, uzyskując tablicę z terminami dla cos (x) i tablicę z terminami sin (x), ponieważ „rzędy macierzy”{...}/
ponownie wykonują blok dla każdego elementu tablicy (wiersz macierzy):-
:+
dodaje elementy rzędu macierzy razem-
6mO
zaokrągla do 6 miejsc po przecinkuW tym momencie mamy pożądane cos (x), a sin (x) na stosie
p
drukuje reprezentację ostatniego elementu na stosie (sin (x)), po którym następuje nowa liniaAt na końcu programu pozostała zawartość stosu (cos (x)) jest drukowana automatycznie.
źródło
Perl - 72 bajty
Lub licząc opcje wiersza poleceń jako 1 bajt każdy, w 70 bajtach :
Lub, jeśli pozwolisz mi Perl 5.8, w 63 bajtach :
ale dlaczego miałbyś
Edycja : zgodność z nowymi regułami.
%f
zaokrągla domyślnie do 6 miejsc, jakie to wygodne!Algorytm
Badanie serii Taylora pod kątem grzechu (x) :
można zauważyć, że każdy termin równomiernie dzieli każdy kolejny termin. Z tego powodu można go bez trudu przekształcić w wyrażenie zagnieżdżone:
cos (x) przekształca się podobnie, bez wiodącego x , a mianownik jest o jeden mniejszy.
Dodatkowo to zagnieżdżone wyrażenie może zostać przeformułowane jako odwrotne wyrażenie rekurencyjne:
ze s ∞ = 0 i sin (x) = x · s 1 , który jest ostatecznie używany.
Nie golfił
Przykładowe użycie
Jeśli chcesz to przetestować online, polecam korzystanie z compileonline.com . Skopiuj i wklej kod
main.pl
, a następnie dane wejściowe wSTDIN
polu Execute Script.źródło
Python 3 (102) / Python 2 (104)
Python 3 (102)
Python 2.7 (104)
Zasadniczo ten sam kod. Oszczędzamy dwie postacie przed niepotrzebnymi parenami,
print
ale tracimy cztery z potrzebyraw_input
.Przykładowy przebieg
Możesz je uruchomić tutaj .
Wyjaśnienie kodu
Główną ideą jest obliczenie
2*n
warunkówe^(ix)
, a następnie wzięcie części wyobrażonej i rzeczywistej, aby uzyskać wartościsin
icos
przybliżone don
warunków. Używamy skrótu z serii Taylor:Jest to wielomian w i * x, ale zamiast obliczać jego wartość sumując każdy termin, używamy zmodyfikowanej metody Hornera do obliczania sekwencji (zdefiniowanej rekurencyjnie w odwrotnej kolejności)
co daje
t_1
wyrównanie pożądanej wartości.Operacje formatowania napisów w języku Python służą do wyświetlania wartości w zaokrągleniu do 6 cyfr dziesiętnych.
Edycja: zmieniono na okrągłe do 6 cyfr zgodnie z nowymi zasadami. Żadne inne zmiany nie były potrzebne.
źródło
J
98 70 6958Chociaż można to prawdopodobnie nieco skrócić, używając bardziej fantazyjnych funkcji ... komentarze są mile widziane:
Uwaga 2: Wejście kończy się po otrzymaniu EOF (Ctrl-D w Linuksie). Edycja: połączyć potęgowanie oraz silnia w ładniejszy, bardziej J ish całości:
($ %&(*/) >:@i.@[ )
. Sprowadza się to do pobrania tablicy x replikacji yi tablicy liczb od 1 do y. Pomnóż każdy i podziel wynik. Pozbywa się duplikatu*/
.Dzięki algortihmshark kolejne 7 znaków jest wyłączone.
Wyeliminowano cięcie, aby pozbyć się nowej linii.
Dłuższa wersja, dla której niezbędna jest znajomość widelców.
Nie ma internetowego tłumacza języka J, ale jest to oprogramowanie typu open source od kilku lat; instalacja jest łatwa dzięki następującym instrukcjom:
http://www.jsoftware.com/jwiki/System/Installation/J801
Na #jsoftware na irc.freenode.org jest też bot J.
stdin działa tylko wtedy, gdy wybiegł z pliku, z linii poleceń, jeszcze wymienić
stdin ''
z'a b;'
gdzie aib to numery, które zostały przekazane na polecenia.źródło
exit
&
z,0j6&":
aby zapisać znak. Ponadto,(i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)
mogą być zapisane(($%&(*/)1+i.@[)"0~i.@,&_2)/
na innym 6.T.
(przybliżona funkcja według n-termicznej serii Taylora), ale myślę, że to słowo werbalne jako standardowa luka.Perl,
1201081048985Nie golfowany:
Pierwszy wiersz odczytuje dane wejściowe i używa wyrażenia regularnego, aby znaleźć spację; to automatycznie umieszcza wartość przed spacją w $ `i wartość po niej w $ '.
Teraz zapętlamy od 1 do
2*n-1
.$t
jest naszym terminem, który pętla wielokrotnie mnożyx
i dzieli przez indeks pętli ($_
). Pętla rozpoczyna się od 1 zamiast 0, ponieważ cosinus jest inicjowany na 1, co pozwoliło mi uniknąć dzielenia przez zero.Po aktualizacji
$t
operator trójkowy zwraca albo,$sine
albo$cosine
, w zależności od tego, czy indeks jest nieparzysty czy parzysty, i dodaje$t
do niego wartość. Magiczna formuła$_&2?-$t:$t
mówi, czy dodać lub odjąć tę wartość (w zasadzie używając bitowego - i na indeksie i 2, aby wygenerować powtarzającą się sekwencję „dodawaj, dodawaj, odejmuj, odejmuj”).Możesz przetestować ten kod na stronie compileonline.com .
źródło
20 20
.1..$n*2-1
zamiast tego może być konieczne skorzystanie z pętli for1..$n
. Podczas gdy tu jestem ...$s
jest całkowicie w porządku, niezainicjowany, jakundef
ocenia się0
w kontekście liczbowym. Trójargumentowy zadanie nie wymaga nawiasów:$_&1?$s:$c+=$t
."%.8f\n%.8f"
można skrócić do"%.8f\n"x2
, w wyniku dodania końcowego nowego wiersza.$t*(1-($_&2))
=>$_&2?-$t:$t
.Fortran:
8910912510210198 bajtówNadużywam niejawnego pisania, ale niestety nie istnieje żaden taki niejawny złożony typ, więc musiałem podać to i kompleks
i
.Gfortran naturalnie zmniejsza wydajność w 8 miejscach po przecinku, więc jesteśmy dobrzy w tej specyfikacji.Niestety, moja oryginalna metoda wyjściowaprint*,t
nie spełniała specyfikacji, więc musiałem dodać 16 znaków, aby uzyskać wyimaginowane i rzeczywiste komponenty i uzyskać wymagane 8 miejsc po przecinku.Dzięki Ventero udało mi się zaoszczędzić 23 bajty między wyjściem a pętlą. I kolejny znak, aby uzyskać poprawne odpowiedzi i sformatowane wyjście. I jeszcze 3 na
read
wyciągu.Bez golfa,
źródło
C 120
Aby zapisać bajt, instrukcje aktualizujące wartość sinusoidalną są umieszczane wewnątrz
for()
instrukcji, ale w rzeczywistości są wykonywane po instrukcjach następujących po nawiasie zamykającym, który aktualizuje wartość cosinusową. (Chyba mógłbym również zaoszczędzić kilka bajtów, usuwając końcowy znak nowej linii w danych wyjściowych programu).Zmienne globalne
s
,c
,r
ix
są niejawnie inicjowany do zera, ii
będzie miał wartość 1 tak długo, jak nie ma argumentów przedstawionych w wierszu poleceń. Niestetyprintf()
domyślnie jest to 6 miejsc po przecinku, więc format wyjściowy jest nieco wyczerpujący.Nie golfowany:
Oto kod z niewielkimi zmianami, aby porządek, w którym wszystko zostało zrobione, był nieco wyraźniejszy:
Przykładowe dane wyjściowe:
Wypróbuj online:
http://ideone.com/URZWwo
źródło
Python> = 2.7.3,
186184211200182170 znakówTrochę jak diabli. Używa wzoru z pytania sparametryzowanego dla sinusa i cosinusa.
Tłumacz online można znaleźć
tutajtutajEdycja: Ważna wersja ze wszystkimi ograniczeniami
Edycja2: Zmieniono interpreter online na ideone.com z powodu nieprawidłowego
round
działania funkcji w Pythonie 2.7.1Edycja3: Okazało się, że użyłem niepotrzebnej inline lambda + zmieniłem zaokrąglanie na format ciągu (skradziony z xnor :))
Edit4: Zastąpiony niedziałającą
join
głównąfor
pętląźródło
**
sądzę). Myślę więc, że będziesz musiał zredagować swoją odpowiedź. Przepraszamy za niedogodności. Proszę, popraw mnie jeśli się mylę.20 20
, otrzymuję dane wyjściowe-5364.4118142500001
. Może chcę to naprawić do 8 miejsc po przecinku.2.7.1
. Jeśli uruchomisz go na ideone.com (Python 2.7.3), działa poprawnie. ideone.com/JsYNNKJavaScript - 114 znaków
Na podstawie świetnej odpowiedzi Jamesa. Ten sam algorytm, z pominięciem pierwszego kroku przy inicjalizacji c = 1 is = x. Użycie 2 zmiennych zamiast tablicy dla danych wyjściowych upraszcza pętlę.
Nie golfił
źródło
s += (l *= x / ++d)
a nies += (l* = x / ++d)
w nie golfowym kodzie.JavaScript (wersja robocza ECMAScript 6) -
9796 znakówRozwiązanie rekurencyjne:
Wynik:
źródło
no functions
wymagań.C, 114
Niewystarczająca reputacja do komentowania, ale w odpowiedzi na odpowiedź C Squeamisha Offisrage'a , redukcja 7 bajtów poprzez użycie liczby zmiennoprzecinkowej do podwójnego i usuwania spacji oraz połączenie deklaracji i inicjalizacji „r” daje
spróbuj tutaj .
źródło
r
w deklaracji. Nie testowałem, aby sprawdzić, czyfloat
daje wymaganą precyzję.float
że dałbym wymaganą precyzję, ale to działa :) Witamy w PPCG, user2702245!float
zmiennymi? Zax=5
in=3
dostajęsin(x)=10.20833206
icos(x)=14.54166412
:-( (Intel Core Duo, na wypadek gdybyś się zastanawiał)GNU bc, sterowany przez bash, 128 bajtów
Zbyt wiele bajtów wydano na ustawienie miejsc po przecinku i na najbliższe zaokrąglenie. No cóż, tutaj jest tak:
Wynik:
Narzędzia wiersza polecenia systemu Linux, 97 znaków Unicode
Odpowiedź hacka Unicode usunięta na żądanie OP. Spójrz na historię edycji, jeśli jesteś zainteresowany.
źródło
Ruby, 336
Prawdopodobnie najdłuższy tutaj, ale jestem pewien, że można go skrócić :(
źródło
JavaScript (ES6) - 185 znaków
Korzysta z funkcji
q
silnia,i
potęgowania ip
wykonywania zarówno, jaksin
icos
. Uruchom na jsbin.com. Używa dokładnie formuły bez żadnych modyfikacji.EDYCJA : Zmieniono
8
miejsca6
dziesiętne na miejsca dziesiętne. 15 / maja / 14Nieskluczony kod :
źródło
JavaScript - 133 znaki
Nie golfił
źródło
Mathematica, 96 znaków
źródło
x,n
?x n
.Ruby -
160152140 znakówWykorzystując rekurencję i fakt, że dla tej rekurencyjnej implementacji sin (x, 2n + 1) = 1 + cos (x, 2n - 1), będąc sin (x, n) i cos (x, n), szereg zdefiniowany powyżej dla cos x i sin x.
Edycja: przesłane przez komentujących (czytaj poniżej).
źródło
p=->x,n{...}
,f=->n{...}
i tak dalej, a następnie za pomocą nawiasów kwadratowych nawiasach zamiast do nich zadzwonić, jakp[x,n-1]
. Myślę też, żecollect
jest to po prostu aliasmap
, który jest znacznie krótszy, a ponieważ mapujesz tylko połączenie członka, możesz go skrócićgets.split.map &:to_f
.