Pedant'ın kosinüsü


29

Patronum az önce bir kosinüs işlevi yazmamı söyledi. İyi bir matematik meraklısı olarak, aklımdan hemen uygun Taylor Serisi çağrıştırdı.

cos(x) = 1 / 0! - x^2 / 2! + x^4 / 4! - x^6 / 6! + ... + (-1)^k x^(2k) / (2k)! + ...

Ancak, patronum çok seçici. Taylor Serisinin tam olarak kaç terimini hesaplayacağını belirtmek istiyor. Bu işlevi yazmama yardım eder misin?

Senin görevin

'Den kayan nokta değeri xve' 0den küçük olan 2 pibir pozitif tamsayı verildiğinde, yukarıda verilen Taylor serisinin ilk terimlerinin toplamını hesaplayın .n100ncos(x)

Bu , yani en kısa kod kazanır. Giriş ve çıkış, standart yollardan biriyle alınabilir. Standart boşluklar yasaktır.

notlar

  • Girdi xve arasında açık bir ayrım olduğu sürece makul herhangi bir biçimde alınabilir n.
  • Giriş ve çıkış, en azından bazı standart yuvarlama kurallarına sahip tek duyarlıklı IEEE kayan nokta sayılarını kullanarak formülü hesaplamak kadar kesin olan kayan nokta değerleri olmalıdır.
  • Kullanılan dil için mantıklıysa, kesin rasyonel miktarlar kullanılarak hesaplamalar yapılabilir, ancak girdi ve çıktı hala ondalık biçimde olacaktır.

Örnekler

 x  |  n | Output
----+----+--------------
0.0 |  1 | 1.0
0.5 |  1 | 1.0
0.5 |  2 | 0.875
0.5 |  4 | 0.87758246...
0.5 |  9 | 0.87758256...
2.0 |  2 | -1.0
2.0 |  5 | -0.4158730...

1
Bunun nda daha büyük olduğunu varsayıyorum 0?
GamrCorps

8
Teknik olarak pedant'ın ne anlama geldiğini söyleyemem ama bu çok meta olurdu.
PyRulez

8
Patronunuz iyi ya da en azından okunabilir bir işlev yazmanızı istiyorsa, yanlış yerdesiniz.
Roman Gräf

2
Bir gerçekten seçici patron ... Taylor serisi biraz daha verimli (ve doğru) bir şey kullanarak hesapla kosinüs isteyeyim
PM 2Ring

6
@ PM2Ring Seçici olmaz, mantıklı olur. Taylor serisi gerçekten en kaba seçenek.
user1997744

Yanıtlar:


64

İşlem Flashpoint komut dosyası dili, 165 157 bayt

F={x=_this select 0;n=_this select 1;i=0;r=0;while{i<n*2}do{r=r+x^i/(i call{c=_this;j=c-1;while{j>0}do{c=c*j;j=j-1};if(c<1)then{c=1};c})*(-1)^(i/2);i=i+2};r}

İle ara:

hint format["%1\n%2\n%3\n%4\n%5\n%6\n%7",
    [0.0, 1] call f,
    [0.5, 1] call f,
    [0.5, 2] call f,
    [0.5, 4] call f,
    [0.5, 9] call f,
    [2.0, 2] call f,
    [2.0, 5] call f]

Çıktı:

enter image description here

Giriş ve çıkış, en azından bazı standart yuvarlama kurallarına sahip tek duyarlıklı IEEE kayan nokta sayılarını kullanarak formülü hesaplamak kadar kesin olan kayan nokta değerleri olmalıdır.

Basılı çıktıda daha uzun ondalık sayılar kesin olmasa da, sayıların tek duyarlıklı IEEE kayan nokta sayıları olduğundan oldukça eminim. Bu sayıları böyle yuvarlayan baskı, aslında sayılar daha kesin.

Örneğin, şunu a=1.00001;b=1.000011;hint format["%1\n%2\n%3", a, b, a==b]gösterecek:

1.00001
1.00001
false

Bu nedenle, açıkça sayılardaki gerçek hassasiyet, basılı hassasiyetten daha büyüktür.



16
@orlp Neden olmasın?
Steadybox

3
@orlp Bence sorulması gereken en uygun soru şudur: Operation Flashpoint kodlama dili neden ArnoldC'un bir türevi değildir ?
ceilingcat

2
Hmmm… Girilen girilen sayıyı [n] verilen pusula yönüne [x] vurarak giriyor musunuz? 😍 Operasyon Flashpoint!
Mormegil

14
@Mormegil Genelde hayır, ancak bu kodun parçasıyla yapılabilir: dir=-1;num=1;player addEventHandler ["fired", {_dir=getdir (nearestObject [_this select 0, _this select 4]);if (dir < 0) then {dir = _dir} else {if (abs(dir - _dir) < 5) then {num = num + 1} else {hint format["%1", [dir*(pi/180), num] call F];dir=-1;num=1}}}]- Bir yöne çekmek sayacı artırır ve daha sonra başka bir yöne çekmek kosinüs işlevini önceki yöne ve bu yöndeki çekim sayısına göre çağırır.
Steadybox

13

05AB1E , 14 11 bayt

FIn(NmN·!/O

Çevrimiçi deneyin!

açıklama

F                # for N in [0 ... n] do
 In              # push (x^2)
   (             # negate
    Nm           # raise to the Nth power
      N·!        # push (2*N)!
         /       # divide
          O      # sum

@JamesHolderness: Evet, dil o zamandan beri oldukça büyük bir revizyondan geçti. Garip bir böcek etkilenmiş gibi görünüyor ², ancak bunun yerine yerini alabilir I.
Emigna

10

MATL , 14 bayt

U_iqE:2ep/YpsQ

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

Örnek ile açıklama

Tüm sayılar çift duyarlığa sahiptir (varsayılan ayardır).

Girişlerini düşünün x = 2.0, n = 5.

U_     % Implicitly input x. Square and negate
       % STACK: -4
iqE    % Input n. Subtract 1, multiply by 2
       % STACK: -4, 8
:      % Range
       % STACK: -4, [1 2 3 4 5 6 7 8]
2e     % Reshape into a 2-row matrix
       % STACK: -4, [1 3 5 7;
       %             2 4 6 8]
p      % Product of each column
       % STACK: -4, [2 12 30 56]
/      % Divide, element-wise
       % STACK: [-2 -0.333333333333333 -0.133333333333333 -0.0714285714285714]
Yp     % Cumulative product of array
       % STACK: [-2 0.666666666666667 -0.0888888888888889 0.00634920634920635]
s      % Sum of array
       % STACK: -1.41587301587302
Q      % Add 1. Implicitly display
       % STACK: -0.41587301587302

10

Mathematica, 49 41 39 31 bayt

Sum[(-#^2)^k/(2k)!,{k,0,#2-1}]&

Eski, daha "eğlenceli" versiyon: (39 bytes)

Normal@Series[Cos@k,{k,0,2#2-2}]/.k->#&

@Pavel ve 8 @Greg Martin sayesinde 8 bayt kaydedildi!


9
Mathematica'nın Serieskabiliyeti gerçekten harika ve eğlenceli olsa da, elle yapılan uygulamanın Sum[(-#^2)^k/(2k)!,{k,0,#2-1}]&burada daha kısa olduğu ortaya çıkıyor .
Greg Martin,

9

Jöle , 12 11 bayt

ḶḤµ⁹*÷!_2/S

Çevrimiçi deneyin!

Nasıl?

ḶḤµ⁹*÷!_2/S - Main link: n, x           e.g. 5, 2.0
Ḷ           - lowered range(n)              [0,1,2,3,4]
 Ḥ          - double (vectorises)           [0,2,4,6,8]
  µ         - monadic chain separation (call that i)
   ⁹        - link's right argument         2.0
    *       - exponentiate(i) (vectorises)  [1.0,4.0,16.0,64.0,256.0]
      !     - factorial(i) (vectorises)     [1,  2,  24,  720, 40320]
     ÷      - divide (vectorises)           [1.0,2.0,0.6666666666666666,0.08888888888888889,0.006349206349206349]
        2/  - pairwise reduce by:
       _    -     subtraction               [-1.0,0.5777777777777777,0.006349206349206349]
         S  - sum                           -0.41587301587301617

8

Jöle, 22 bayt

-*ð×ø⁹*⁸²ð÷ø⁸Ḥ!
⁸R’Ç€S

Bu, ilk argümanı n, ikinciyi x olarak alan tam bir programdır.

Açıklama:

              Creates a function to compute each term in the series. 
Its argument we will call k, eg k=3 computes 3rd term. Take x=2 for example.
-*           Computes (-1)^k. Eg -1
ð×ø        Multiplies by the quantity of
⁹             x.  
*             to the power of
⁸             k
²             ...squared. Eg -1 × (2³)² 
ð÷ø        divides by the quantity of
⁸              k
Ḥ             doubled
!               ...factorial. Eg -1 × (2³)²/(6!).


                Main link, first argument n and second argument n. Eg n=4, x=2.
⁸R            Creates range(n). Eg [1,2,3,4]
’                Decrements each element. Eg [0,1,2,3]
Ç€            Maps the above function over each element. Eg [1,-2,0.666,-0.0889]
S               Sum all all of the elements.  Eg -0.422.

7
PPCG'ye Hoşgeldiniz!
Martin Ender

6

Python, 54 bayt

f=lambda x,n,t=1,p=1:n and t+f(x,n-1,-t*x*x/p/-~p,p+2)

Python 2 kullanıyorsanız, x'i bir tamsayı olarak değil, bir kayan nokta olarak geçirdiğinizden emin olun, ancak benim anladığım kadarıyla Python 3 kullanıyorsanız önemli değil.


5

TI-Basic, 41 40 bayt

Prompt X,N
sum(seq((-(X+1E-49)2)^Q/((2Q)!),Q,0,N-1
1E-49 açıya eklenir çünkü TI-Basic 0 ^ 0 için bir hata verir, hataya neden olmayacak kadar büyüktür ve cevabı değiştirebilecek kadar büyük değildir.


4

C, 96 bayt

Özyinelemeli Canlı

f(n){return n?n*f(n-1):1;}float c(n,x)float x;{return n?c(n-1,x)+pow(-1,n)*pow(x,2*n)/f(2*n):1;}

Detaylı

f(n) // factorial(n)
{
    return n ?   // n != 0 ?
        n*f(n-1) // n! = n * (n-1)!
    : 1;         // 0! = 1
}

float c(n,x)float x; // cos(x) with n+1 terms
{
    return n ?        // n != 0 ?
        c(n-1, x)     // cos(x) (n-1)th term
        + pow(-1, n)  // + (-1)^n
        * pow(x, 2*n) // * x^(2n)
        / f(2 * n)    // / (2n)!
    : 1;              // cos(x) at n=0
}

Progressive Recursive, 133 bayt Canlı

#define F float
#define c(x,n) 1+g(1,n,x,1,1,1)
F g(F i,F n,F x,F s,F p,F f){s=-s;p*=x*x;f*=i;return i<n?g(i+1,n,x,s,p,f)+s/2*p/f:0;}

Detaylı

#define F float // shorthand float

#define c(x,n) 1+g(1,n,x,1,1,1) // macro function

F g(F i,F n,F x,F s,F p,F f)
{
    s = -s;   // (-1)^n = (-1) * (-1)^(n-1)
    p *= x*x; // x^(2n) =  x^2 * x^(2(n-1))
    f *= i;   //    2n! =    2 * (1*2*..*n)

    return i < n ?       // i = 0 .. n-1
        g(i+1,n,x,s,p,f) // next term
        + s / 2 * p / f  // s*p/2f = s/2*p/f
        : 0;             // don't compute nth term
}

96b sürümü c(0.5, 80)=> NaN, taşma içinf(80)=0
l4m2

@ l4m2 özyinelemeli fonksiyonlar golf oynamak için buradalar, ancak çağrı sayıları çağrı yığını sınırını aştığı için kolayca taşabilecekleri için pratik değiller. Küçük sayılar
Khaled.K,

1
Doğrudan doğrudan sorun, demek n<100ki en azından menzilde bu kadar ileri gitmeyin. Taşması değil
l4m2

Eğer sorun söyler n<100ve O(2^n)çözüm kullanırsanız, sanırım sorun değil, sonuçta sonuç retuan olduğu sürece
l4m2

1
Bilginize, NaN sonucunun özyinelemeyle hiçbir ilgisi yoktur - bu, float kullanması gerektiğinde tamsayı kullanan faktoring hesaplamasının taşmasıdır (198! Asla bir int'e uymaz).
James Holderness,

4

JavaScript (ES6), 46 bayt

f=
x=>g=(n,t=1,p=0)=>n&&t+g(--n,-t*x*x/++p/++p,p)
<div oninput=o.textContent=f(x.value)(n.value)><input id=x><input type=number min=1 value=1 id=n><pre id=o>1

Kıvrımlı girişleri alır (x) (n).


Neden pasajı yapmıyorsun?
Arjun

4

C, 71 bayt

Horner şemasını kullanarak

float f(n,x)float x;{float y;for(n+=n;n;)y=1-(y*x*x/n--)/n--;return y;}

Ungolfed versiyonu:

float f(n,x) float x;
{
  float y = 0.0;
  for(n = 2*n; n>0; n -= 2)
  {
    y = 1-y*x*x/n/(n-1);
  }
  return y;
}

Bu hangi platformda çalışıyor?
anatolyg

4

R, 70 64 bayt

function(x,n)sum(sapply(1:n-1,function(y)(-x^2)^y/gamma(2*y+1)))

pizzapants184 'ın (-x ^ 2) ^ y numarası ile verdiği cevap sayesinde 6 bayt kurtardı

65 bayt:

function(x,n)Reduce(function(a,b)a+(-x^2)^b/gamma(2*b+1),1:n-1,0)

hemen hemen bunun saf bir şekilde uygulanmasına rağmen, küçük bir golf oynadı; Taylor serisini belirtilen değere göre hesaplayan anonim bir işlev döndürür

  • Bir Küçültme kullanmak, bir bayt daha alır. init ayarlanması
  • gamma(n+1)yerine kullanırfactorial(n)
  • 1:n-1 eşittir 0:(n-1)

3

tamam , 38 bayt

Bu aynı zamanda k olarak da çalışır , ancak 39 bayt alır çünkü bir tanesinin yerine 'yazılmış olması gerekir /:(en azından 2016.06.28 km'de).

{+/(y#1 -1)*{(*/y#x)%*/1+!y}.'x,'2*!y}

Açıklama:

Orta uçtan başlayalım. (*/y#x)üstel, eşdeğerdir x^y. */1+!yolabilir y!veya yfaktörlü. %bölünmedir. Bu nedenle ortadaki işlevmiddle(x,y) = (x^y)/(y!) .

Şimdi sağdaki bit, yukarıdaki işlevin uygulandığı. 2*!yolduğunu {0, 2, 4, ..., 2*(y-1)}. x,'prepends xdönüştürerek, bu listedeki her öğenin {(x, 0), (x, 2), (x, 4), ..., (x, 2*(y-1))}. O .'zaman middleher sayı çifti için ( mapesasen) uygulanır.

Son olarak, (y#1 -1)*sonucu 1 veya -1 (alternatif) ile çarpar +/ve toplamı alır.


3

Haskell, 71 Bayt

f x n=sum$map(\i->(-1)^i*x^(2*i)/fromIntegral(product[1..2*i]))[0..n-1]

Bu, deşifre etmek zor olmayan oldukça sıkıcı bir cevap. fromIntegralGerçekten de, ısırır. ( /Operatör Haskell'de aynı sayısal tipte işlenenler gerektirir ve sayısal türler arasında zorlama, wordy işlevi olmadan izin verilmez.)


1
Bir liste anlayışı size birkaç ısırık kurtarabilir:f x n=sum[(-1)^i*x^(2*i)/fromIntegral(product[1..2*i])|i<-[0..n-1]]
Julian Wolf

1
Özellikle PPCG ve Haskell golf oynamalarına hoş geldiniz!
Laikoni

3

Jöle , 12 bayt

²N*Ḷ}©÷®Ḥ!¤S

Çevrimiçi deneyin!

Nasıl çalışır

²N*Ḷ}©÷®Ḥ!¤S  Main link. Left argument: x. Right argument: n

²             Square; yield x².
 N            Negate; yield -x².
     ©         Call the link to the left and copy the result to the register.
   Ḷ}          Call unlength on the right argument, yielding [0, 1, ..., n-1].
  *           Yield [1, -x², ..., (-x²)**(n-1)].
          ¤   Combine the three links to the left into a niladic chain.
       ®        Yield the value in the register, [0, 1, ..., n-1].
        Ḥ       Unhalve; yield [0, 2, ..., 2n-2].
         !      Factorial; yield [0!, 2!, ..., (2n-2)!].
      ÷         Division; yield [1/0!, -x²/2!, ..., (-x²)**(n-1)/(2n-2)!].
           S  Take the sum.


3

Haskell , 61 bayt

x#n=sum[(-1*x^2)^i/fromIntegral(product[1..2*i])|i<-[0..n-1]]

Bu, diğer Haskell çözümünden ayrı bir cevap almak için yeterince farklı görünüyordu. Uygulama oldukça açıklayıcı olmalıdır - kosinüsünün hesaplanacağı x#nyerin nerede xolduğunu ve nalınacak kısmi toplamın sırasını arayın .


Sen kaldırarak epeyce bayt kaydedebilir fromIntegralve kullanma **yerine ^gibi, bu
B. Mehta

x#n=sum[(-x*x)**i/product[1..2*i]|i<-[0..n-1]]3 bayt daha kaydeder.
Lynn

3

Pyt , 37 34 33 bayt

←←ĐĐ↔3Ș1~⇹ř⁻^04Ș⇹ř⁻^²*0↔ř⁻2*!+/+Ʃ

3

J, 26 24 Bayt

+/@:(!@]%~^*_1^2%~])2*i.

@Cole sayesinde -2 bayt

Başlangıçta toplama ve çıkarma arasında geçiş yapmak için döngüsel bir gerund kullanmayı planlamıştım, ancak işe yaramadı.

Açıklama:

                    2*i.     | Integers from 0 to 2(n-1)
    (              )         | Dyadic train:
            _1^-:@]          | -1 to the power of the left argument
          ^*                 | Times left arg to the power of right arg
     !@]%~                   | Divided by the factorial of the right arg
+/@:                         | Sum

1
24 bayt: +/@:(!@]%~^*_1^2%~])2*i.Döngüsel bir çürüğü araştıracağım: J /sağdan sola değerlendirildiği için muhtemelen başarısız oldu, bu yüzden kullanmanız gerekiyor |.(ya da bunu hesaba kattınız ve hala zorluk çektiniz).
cole,

3

Perl 6 , 53 bayt

{(sum (1,*i*$^x...*)[^2*$^n] »/»(1,|[\*] 1..*)).re}

Çevrimiçi deneyin!

Bu aslında karmaşık üstel hesaplar e istenen terim sayısının iki katı ve daha sonra gerçek katılmaktadır.


2

Sembolik Matematik Araç Kutusu ile MATLAB, 57 bayt

@(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x))

Bununla Bu tanımlar, bir anonim işlev alır doublegirdileri x, nve a olarak oluştururdouble.

Örnek (R2015b'de test edilmiştir):

>> @(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x))
ans = 
    @(x,n)eval(subs(taylor(sym('cos(x)'),'Order',2*n),'x',x))
>> f = ans; format long; f(0,1), f(0.5,1), f(0.5,2), f(0.5,4), f(0.5,9), f(2,2), f(2,5)
ans =
     1
ans =
     1
ans =
   0.875000000000000
ans =
   0.877582465277778
ans =
   0.877582561890373
ans =
    -1
ans =
  -0.415873015873016

2

JavaScript ES7 60 bytes

x=>a=n=>--n?(-1)**n*x**(2*n)/(f=m=>m?m*f(m-1):1)(2*n)+a(n):1


x=>a=n=>                                                         // Curry-d function, it basically returns another function
        --n?                                              :1  // subtract one from n. If n - 1 is 0, return 1
            (-1)**n*                                             // This generates the sign of the number
                    x**(2*n)/                                    // This creates the part before the division, basicaly x^2n
                             (f=m=>m?m*f(m-1):1)(2*n)            // This creates a recursive factorial function and calls it with 2n
                                                     +a(n)    // Recursively call the function. This adds the elements of the taylor series together

To use it:

Press F12, type in the function and then do

c(x)(n)

2

C 144 130 bytes

F(m){int u=1;while(m)u*=m--;return u;}float f(float x,n){float s;for(int i=1;i<n;i++)s+=pow(-1,i)*pow(x,2*i)/(F(2*i));return 1+s;}

Ungolfed Version:

//Function to calculate factorial
int F(int m)
{
  int u=1;

  while(m>1)
   u*=m--; 

  return u;
}

//actual function called in main function   
float f(float x, int n)
{

  float s=0.0;

  for(int i=1;i<=n-1;i++)
     s+=pow(-1,i)*pow(x,2*i)/(F(2*i)); 

  return 1+s;
 }

Thanks Kevin for saving some bytes!


You can save a few bytes by massaging the function definitions: F(m){...}f(x,n)float x;{...}
Kevin

Since u * 1 == u, you can make the loop in the first function either while(m)u*=m-- or u=m;while(--m)u*=m (same length)
Kevin

i<=n-1 is the same as i<n
Kevin

@Kevin Thanks, you're absolutely right, have not golfed in a while now. :)
Abel Tom



2

Stax, 12 bytes

ü┘·.ⁿYeò≥Vîû

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

            Input is `x n`
Z           Push a zero underneath the top.  The stack is now `x 0 n` 
D           Run the rest of the program n times.
  xJNi|*    (-x*x)^i where i is the iteration index
  iH|F/     divide that by factorial(2i)
  +         add to the running total so far
            final result is implicitly printed

Run this one



1

PHP, 76 bytes

for($f=1;$i<$argv[2]*2;$f*=++$i)$i&1?:$s+=(-1)**$k++*$argv[1]**$i/$f;echo$s;

takes X and N from command line arguments; run with -r.

loop $i from 0 to N*2-1, hold fac($i) in $f; if $i is even, add term to sum$s. print sum.


I wish I had complex numbers (with M_I as imaginary unit);
I would simply multiply $f with M_I*++$i and save 7 bytes.

Maybe Mathematica can do that. But Mathematica doesn´t have to.

I could save two bytes with cos(M_PI*$i/2) instead of $i&1?: and (-1)**$k++;
but it would feel a bit odd to use a cosine builtin to build a cosine function.


1

Axiom, 36 bytes

g(a,n)==eval(taylor(cos(x)),a).(2*n)

Build the infinite (in the meaning finite but one can ask to build the list of 2*n elements if PC has enough memory) list of partial sums for the Taylor series for cos(x) calculate in 'a', in "eval(taylor(cos(x)),a)"; gets the 2*n element of that list in ".(2*n)". Test cases:

(47) -> g(0,1)
   (47)  1
                                                 Type: Expression Integer
(48) -> g(0.5,1)
   (48)  1.0
                                                   Type: Expression Float
(49) -> g(0.5,2)
   (49)  0.875
                                                   Type: Expression Float
(50) -> g(0.5,4)
   (50)  0.8775824652 7777777778
                                                   Type: Expression Float
(51) -> g(0.5,9)
   (51)  0.8775825618 9037271611
                                                   Type: Expression Float
(52) -> g(2.0,5)
   (52)  - 0.4158730158 7301587302
                                                   Type: Expression Float
(53) -> g(2.0,800)
   (53)  - 0.4161468365 471423870

1

J, 17 bytes

4 :'2&o.T.(+:y)x'

Try it online!

Uses a built-in, which I assume is OK.

Unfortunately, I don't really know how to work well with functions that take arguments via currying like this, so I had to do this explicitly. I'm sure that there is a way to do it tacitly or shorter.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.