ペダルのコサイン


29

上司からコサイン関数を書くように言われました。数学のオタクとして、私の心はすぐに適切なテイラーシリーズを思いつきました。

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

しかし、私の上司はとてもうるさいです。彼は、計算するテイラー級数の項の数を正確に指定できるようにしたいと考えています。この関数を書くのを手伝ってもらえますか?

あなたのタスク

to xからの浮動小数点値とより小さい正の整数が与えられた場合、上で与えられたのテイラー級数の最初の項の合計を計算します。02 pin100ncos(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
私は彼らが技術的にはつまらないものを意味しているとは思いませんが、それはメタすぎるでしょう。
PyRulez

8
上司が、良いまたは少なくとも読み取り可能な機能を記述したい場合は、間違った場所にいます。
ローマングラフ

2
本当にうるさい上司は...テイラー級数より少し効率的(かつ正確な)何かを使用して計算余弦に望む
PM 2Ring

6
@ PM2Ringそれはうるさくないでしょう、それは合理的です。テイラー級数は本当に最も粗いオプションです。
-user1997744

回答:


64

操作Flashpointスクリプト言語、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]を撃って入力を入力しますか?😍操作引火点!
モルメギル

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

05AB1E14 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ます。
エミグナ

10

MATL、14バイト

U_iqE:2ep/YpsQ

オンラインでお試しください!または、すべてのテストケースを確認します

例付きの説明

すべての数値は倍精度です(これがデフォルトです)。

入力を考えてみましょうx = 2.0n = 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}]&ここでは手作業による実装が短いことがわかります。
グレッグマーティン

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を取り、2番目の引数として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へようこそ!
マーティンエンダー

6

Python、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-Basic、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
}

96bバージョンc(0.5, 80)=> NaN、オーバーフロー用f(80)=0
l4m2

@ l4m2の再帰関数はゴルフを目的としていますが、呼び出し回数が呼び出しスタックの制限を超えると簡単にオーバーフローする可能性があるため、非現実的です。小さい数字。
Khaled.K

1
問題は直接言っているn<100ので、少なくともあなたはその範囲には行かない。スタックオーバーフローではない
-l4m2

問題が発生しn<100O(2^n)解決策を使用する場合、結果を最終的に拒否する限り問題ありません
-l4m2

1
参考までに、NaNの結果は再帰とは関係ありません。浮動小数点数を使用する必要があるときに整数を使用する階乗計算のオーバーフローです(198!はintに収まりません)。
ジェームズホルダーネス

4

JavaScript(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)を取ります。


スニペットにしてみませんか?
アルジュン

4

C、71バイト

Hornerスキームを使用

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

これはどのプラットフォームで機能しますか?
アナトリグ

4

R、70 64バイト

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

(-x ^ 2)^ yトリックによるpizzapants184の回答のおかげで6バイト節約

65バイト:

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

これのほとんどの素朴な実装ですが、わずかなゴルフです。指定されたnに対してテイラー級数を計算する匿名関数を返します

  • Reduceを使用すると、もう1バイト必要です。 init、0に設定する必要があるため必要です。
  • 使用する gamma(n+1)の代わりに、factorial(n)
  • 1:n-1 に等しい 0:(n-1)

3

oK、38バイト

これはkでも機能しますが、代わりに(少なくともkmac 2016.06.28では)として記述する必要があるため、39バイトかかります'/:

{+/(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

Haskell、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]]
ジュリアンウルフ

1
特にPPCGとHaskellゴルフへようこそ!
ライコニ

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#nwhereを呼び出します。xn


あなたは除去することによって、かなりの数のバイトを保存することができますfromIntegralし、使用して**の代わりに^など、この
B.メータ

x#n=sum[(-x*x)**i/product[1..2*i]|i<-[0..n-1]]さらに3バイト節約します。
リン


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.循環動名詞を調査します。Jは/右から左に評価するため、おそらく失敗し|.ます。
コール


2

Symbolic Math Toolboxを使用したMATLAB、57バイト

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

これは、かかるものと匿名関数定義doubleの入力をxnそしてその結果を出力します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

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

いくつかのバイトを保存してくれたケビンに感謝します!


関数定義をマッサージすることで、数バイト節約できますF(m){...}f(x,n)float x;{...}
ケビン

u * 1 == uなので、最初の関数でループを作成するかwhile(m)u*=m--u=m;while(--m)u*=m(同じ長さ)
ケビン

i<=n-1と同じですi<n
ケビン

@ケビンありがとう、あなたは絶対に正しい、今しばらくゴルフをしていません。:)
アベルトム



2

スタックス、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バイト

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

とりXN、コマンドライン引数から。で実行し-rます。

ループ$iから0N*2-1、保留fac($i)$f。場合$iでもあり、合計に用語を追加$s。合計を印刷します。


複素数(M_I虚数単位として)があればいいのに。
単純に7バイトを掛け$fM_I*++$i保存します。

おそらくMathematicaでそれができるでしょう。しかし、Mathematicaは必要ありません。

私は可能性を持つ2つのバイトを保存するcos(M_PI*$i/2)代わりに、$i&1?:(-1)**$k++
しかし、余弦関数を作成するために余弦ビルトインを使用するのは少し奇妙に感じるでしょう。


1

公理、36バイト

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

cos(x)のテイラー級数の部分和のリスト(「有限」という意味ですが、PCに十分なメモリがある場合は2 * n要素のリストを作成することができます)は、「a」、「eval( taylor(cos(x))、a) "; 「。(2 * n)」のリストの2 * n要素を取得します。テストケース:

(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バイト

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

オンラインでお試しください!

ビルトインを使用、これは問題ないと思います。

残念ながら、このようなカリー化を介して引数を取る関数をうまく処理する方法がわからないので、明示的にこれを行う必要がありました。暗黙のうちに、またはもっと短くする方法があると確信しています。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.