페 던트 코사인


29

상사가 방금 코사인 함수를 작성하라고 말했습니다. 좋은 수학 괴짜이기 때문에 내 마음은 즉시 적절한 Taylor Series를 소집했습니다.

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

그러나 내 상사는 매우 까다 롭습니다. 그는 테일러 시리즈의 계산할 항의 수를 정확하게 지정할 수 있기를 원합니다. 이 함수를 작성하도록 도와 줄 수 있습니까?

당신의 작업

x에서 0~ 까지 의 부동 소수점 값 2 pi과 양 n보다 작은 정수 를 고려하여 위에 주어진 Taylor 계열 100의 첫 번째 n항의 합을 계산하십시오 cos(x).

이것은 이므로 가장 짧은 코드가 승리합니다. 모든 표준 방식으로 입력 및 출력을 수행 할 수 있습니다. 표준 허점은 금지되어 있습니다.

노트

  • x와 사이에 명확한 구분이있는 한 입력을 합리적인 형태로 취할 수 있습니다 n.
  • 입력 및 출력은 표준 반올림 규칙이있는 단 정밀도 IEEE 부동 소수점 숫자를 사용하여 공식을 계산하는 것만 큼 정확한 부동 소수점 값이어야합니다.
  • 사용되는 언어가 의미가있는 경우 정확한 합리적인 수량을 사용하여 계산을 수행 할 수 있지만 입력 및 출력은 여전히 ​​10 진수 형식이어야합니다.

 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
나는 n또한 그것보다 크다고 가정합니다 0.
GamrCorps

8
나는 그들이 기술적으로 pedant가 의미하는 것은 아니지만 너무 메타 일 것이라고 말하고 싶습니다.
PyRulez

8
당신의 상사가 당신이 좋은 또는 최소한 읽을 수있는 함수를 작성하기를 원한다면, 당신은 잘못된 곳에 있습니다.
Roman Gräf

2
정말 까다로운 상사가 ... 테일러 시리즈보다 좀 더 효율적으로 (정확한) 뭔가를 사용하여 계산 코사인 원하는 것
오후 2Ring에게

6
@ PM2Ring 까다 롭지 않고 합리적입니다. Taylor 시리즈는 실제로 가장 조잡한 옵션입니다.
user1997744

답변:


64

동작 인화점 스크립팅 언어 165 157 바이트

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}

전화 :

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]

산출:

enter image description here

입력 및 출력은 표준 반올림 규칙이있는 단 정밀도 IEEE 부동 소수점 숫자를 사용하여 공식을 계산하는 것만 큼 정확한 부동 소수점 값이어야합니다.

인쇄 된 출력에서 ​​더 긴 소수가 정확하지는 않지만 숫자는 단 정밀도 IEEE 부동 소수점 숫자라고 확신합니다. 숫자를 반올림하는 인쇄입니다. 실제로는 숫자가 더 정확합니다.

예를 들어 다음 a=1.00001;b=1.000011;hint format["%1\n%2\n%3", a, b, a==b]을 출력합니다.

1.00001
1.00001
false

따라서 숫자의 실제 정밀도는 인쇄 된 정밀도보다 더 큽니다.



16
@orlp 왜 안되죠?
Steadybox

3
@orlp 가장 적절한 질문은 Operation Flashpoint 스크립팅 언어가 ArnoldC 의 변형이 아닌 이유는 무엇입니까?
ceilingcat

2
흠… 주어진 나침반 방향 [x]까지 주어진 라운드 수 [n]를 촬영하여 입력을 입력합니까? 😍 작동 인화점!
Mormegil

14
@Mormegil 일반적으로 아닙니다. 그러나이 코드로 수행 할 수 있습니다 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}}}].-어떤 방향으로 촬영하면 카운터가 증가하고 다른 방향으로 촬영하면 이전 방향의 코사인 함수와 해당 방향의 촬영 횟수가 호출됩니다.
Steadybox

13

05AB1E , 14 11 바이트

FIn(NmN·!/O

온라인으로 사용해보십시오!

설명

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 : 그렇습니다. 그 이후로 언어는 상당히 대대적 인 점검을 거쳤습니다. 이상한 버그가 문제가 된 것 같지만 ²대신 대체 할 수 있습니다 I.
Emigna

10

MATL , 14 바이트

U_iqE:2ep/YpsQ

온라인으로 사용해보십시오!또는 모든 테스트 사례를 확인하십시오 .

예를 들어 설명

모든 숫자는 배정도입니다 (이것이 기본값입니다).

입력을 고려 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 바이트

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

오래되고 더 재미있는 버전 : (39 바이트)

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

@Pavel 덕분에 10 바이트를 절약하고 @Greg Martin 덕분에 8 바이트를 절약했습니다!


9
Mathematica의 Series기능은 정말 대단하고 재미 있지만, 직접 구현 Sum[(-#^2)^k/(2k)!,{k,0,#2-1}]&은 더 짧습니다.
Greg Martin

9

젤리 , 12 11 바이트

ḶḤµ⁹*÷!_2/S

온라인으로 사용해보십시오!

방법?

ḶḤµ⁹*÷!_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

젤리, 22 바이트

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

이것은 n을 첫 번째 인수로 사용하고 x를 두 번째 인수로 사용하는 전체 프로그램입니다.

설명:

              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에 오신 것을 환영합니다!
Martin Ender

6

파이썬, 54 바이트

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

Python 2를 사용하는 경우 정수가 아닌 부동 소수점으로 x를 전달해야하지만 Python 3을 사용하는 경우 중요하지 않습니다.


5

TI 기본, 41 40 바이트

Prompt X,N
sum(seq((-(X+1E-49)2)^Q/((2Q)!),Q,0,N-1
1E-49 TI-Basic이 0 ^ 0에 대해 오류를 발생시키기 때문에 각도에 추가됩니다. 오류를 일으키지 않을만큼 크고 응답을 변경할만큼 크지 않습니다.


4

C, 96 바이트

재귀 라이브

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;}

상세한

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
}

프로그레시브 재귀, 133 바이트 라이브

#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;}

상세한

#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
}

c(0.5, 80)오버플로 96b 버전 => NaNf(80)=0
l4m2

@ l4m2 재귀 함수는 골프를 목적으로 여기에 있지만 호출 수가 콜 스택 제한을 초과하여 쉽게 오버플로 할 수 있기 때문에 비실용적입니다. 더 작은 숫자.
Khaled. K

1
문제는 직접 말 n<100하므로 적어도 범위에서 멀리 가지 마십시오. 스택 오버플로가 아님
l4m2

문제가 있다고 말하고 솔루션 n<100을 사용 O(2^n)하는 경우 결과가 다시 회복되는 한 괜찮습니다.
l4m2

1
참고로 NaN 결과는 재귀와 관련이 없습니다. 정수를 사용해야 할 때 정수를 사용하는 계승 계산의 오버플로입니다 (198!은 int에 절대 적합하지 않습니다).
James Holderness

4

자바 스크립트 (ES6), 46 바이트

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

카레 입력 (x) (n)을 취합니다.


스 니펫으로 만드시겠습니까?
Arjun

4

C, 71 바이트

호너 방식 사용

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

언 골프 버전 :

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;
}

어떤 플랫폼에서 작동합니까?
anatolyg

4

R, 70 64 바이트

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

pizzapants184 덕분에 6 바이트를 절약(-x ^ 2) ^ y 트릭 의 답변

65 바이트 :

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

이것의 거의 순진한 구현이지만 작은 골프를 쳤다. Taylor 시리즈를 계산하는 익명 함수를 지정된 n으로 반환합니다.

  • Reduce를 사용하면 init0으로 설정되어야 하므로 1 바이트 가 더 필요합니다.
  • gamma(n+1)대신에 사용factorial(n)
  • 1:n-1 에 해당 0:(n-1)

3

승인 , 38 바이트

이것은 또한 작동 K ,하지만 걸리는 39 바이트를 한 때문 '으로 작성해야하는 /:대신에 (그것을 수행 능률 협회 컨설팅 2016년 6월 28일에, 적어도).

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

설명:

중간 비트부터 시작하겠습니다. (*/y#x)지수이며,에 해당합니다 x^y. 또는 계승 */1+!y일 수 있습니다 . 부서입니다. 따라서 가운데의 기능은 입니다.y!y%middle(x,y) = (x^y)/(y!)

이제 위의 함수가 적용되는 오른쪽의 비트입니다. 2*!y입니다 {0, 2, 4, ..., 2*(y-1)}. 해당 목록의 모든 항목 x,'앞에 추가 x하여로 바꿉니다 {(x, 0), (x, 2), (x, 4), ..., (x, 2*(y-1))}. 그런 .'다음 middle모든 숫자 쌍에 적용됩니다 (map 기본적으로).

마지막으로 (y#1 -1)*결과에 1 또는 -1 (교대)을 곱하고 +/합을 취합니다.


3

하스켈, 71 바이트

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

이것은 너무 지루하지 않은 꽤 지루한 답변입니다. 는 fromIntegral정말하지만, 물린. (이 /연산자는 Haskell에서 동일한 숫자 유형의 피연산자가 필요하며, 워드 함수가 없으면 숫자 유형 간 강제 변환이 허용되지 않습니다.)


1
목록 이해는 당신에게 약간의 물기를 절약 할 수 있습니다 :f x n=sum[(-1)^i*x^(2*i)/fromIntegral(product[1..2*i])|i<-[0..n-1]]
Julian Wolf

1
특히 PPCG와 Haskell 골프에 오신 것을 환영합니다!
Laikoni

3

젤리 , 12 바이트

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

온라인으로 사용해보십시오!

작동 원리

²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

하스켈 , 61 바이트

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

이것은 별도의 답변을 보증하기 위해 다른 Haskell 솔루션과 충분히 다른 것처럼 보였습니다. 구현은 꽤 자명해야합니다 . 코사인을 계산할 숫자 가 x#n어디 x인지, n부분합의 순서 인지를 호출 하십시오.


당신은을 제거하여 꽤 많은 바이트를 저장할 수 있습니다 fromIntegral및 사용 **대신에 ^같은
B. 메타

x#n=sum[(-x*x)**i/product[1..2*i]|i<-[0..n-1]]3 바이트를 더 절약합니다.
Lynn

3

Pyt , 37 34 33 바이트

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

3

J, 26 24 바이트

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

@cole 덕분에 -2 바이트

원래 순환 반복을 사용하여 덧셈과 뺄셈을 번갈아 가려고했지만 작동하지 못했습니다.

설명:

                    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 바이트 : +/@:(!@]%~^*_1^2%~])2*i.주기적 Gerund를 조사 할 것입니다 : J가 /오른쪽에서 왼쪽으로 평가하기 때문에 실패했을 것이므로 사용해야합니다 |.(또는 아마도 이것을 설명하고 여전히 어려움을 겪었습니다).
cole


2

Symbolic Math Toolbox를 사용한 MATLAB, 57 바이트

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

이것은 그와 익명 함수가 얻어 정의 double입력 x, n와 같은 결과를 출력한다 double.

예 (R2015b에서 테스트) :

>> @(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

자바 스크립트 ES7 60 바이트

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

그것을 사용하려면 :

F12를 누르고 기능을 입력 한 다음

c(x)(n)

2

C 144130 바이트

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;}

언 골프 버전 :

//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;
 }

바이트를 절약 해 준 Kevin에게 감사합니다!


함수 정의를 마사지하면 몇 바이트를 절약 할 수 있습니다.F(m){...}f(x,n)float x;{...}
Kevin

u * 1 == u이므로 첫 번째 함수에서 루프를 만들 while(m)u*=m--거나 u=m;while(--m)u*=m같은 길이로 만들 수 있습니다.
Kevin

i<=n-1i<n
Kevin

@Kevin 고마워, 당신은 절대적으로 맞아, 잠시 동안 골프를하지 않았다. :)
Abel Tom



2

Stax , 12 바이트

ü┘·.ⁿYeò≥Vîû

실행 및 디버깅

포장을 풀고 포장을 풀고 주석을 달았습니다.

            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

이것을 실행



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.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.