極大値と極小値を見つける


14

定義

特定の関数の最大値と最小値は、特定の範囲内または関数のドメイン全体内の関数の最大値と最小値です。

チャレンジ

課題は、任意の方法を使用して、特定の多項式関数の極大値と極小値見つけることです。心配しないでください、私は挑戦を説明して、それをできるだけ単純に保つために最善を尽くします。

入力には、電力の降順または昇順のいずれかで(単一の)単一変数多項式のすべての係数が含まれます。例えば、

  • [3,-7,1] 代表します 3x2 - 7x + 1 = 0
  • [4,0,0,-3] 代表します 4x3-3=0.

解決方法(デリバティブを使用)?

ここで、入力が[1,-12,45,8]であるとしましょう。これは関数にすぎません。x3 - 12x2 + 45x + 8

  1. 最初のタスクは、その関数の導関数を見つけることです。これは多項式関数なので、実際には簡単なタスクです。

    の導関数はです。に存在する定数項は単純に乗算されます。また、加減算された用語がある場合、それらの導関数もそれぞれ加算または減算されます。定数数値の導関数はゼロであることを忘れないでください。以下に例を示します。xnn*xn-1xn

    • x3 -> 3x2
    • 9x4 -> 9*4*x3 = 36x3
    • -5x2 -> -5*2*x = - 10x
    • 2x3 - 3x2 + 7x -> 6x2 - 6x + 7
    • 4x2 - 3 -> 8x - 0 = 8x
  2. ここで、新しい多項式をゼロに等しくすることにより方程式を解き、xの整数値のみを取得します。

  3. これらのxの値を元の関数に入れて、結果を返します。それが出力になるはずです。

前述の例、つまり、を見てみましょう[1,-12,45,8]

  • 入力: [1,-12,45,8]
  • 関数: x3 - 12x2 + 45x + 8
  • デリバティブ-> 3x2 - 24x + 45 + 0 -> [3,-24,45]
  • 方程式を解くと、またはが得られます。3x2 - 24x + 45 = 0x = 3x = 5
  • 今置くx = 3x = 5機能で、我々は値を取得します(62,58)
  • 出力-> [62,58]

仮定

  1. すべての入力係数が整数であると仮定します。これらは、電力の昇順または降順になります。

  2. 入力が少なくとも2次多項式であると仮定します。多項式に整数解がない場合は、何でも返すことができます。

  3. 最終結果は整数のみであると仮定します。

  4. 結果は任意の順序で印刷できます。入力多項式の次数は5を超えないため、コードで処理できます。

  5. 入力は有効であるため、xの解は点ではありません。

また、微分法による強制もありません。任意の方法を使用できます。

サンプルの入力と出力

[2,-8,0] -> (-8)
[2,3,-36,10] -> (91,-34)
[1,-8,22,-24,8] -> (-1,0,-1) 
[1,0,0] -> (0)

得点

これはので、最短のコードが優先されます。


1
私が正しく理解している場合:例では、ステップ「方程式を解く」はあなたのこれまでの挑戦の一部でしょうか?また、「関数にx = 3とx = 5を入れる」というステップは、「派生物」の機能ではなく、「機能」の元の機能を意味しますか?
ケビンクルーッセン

1
サンプルI / O 3について(-1, 0, 1)は、実際の正しい答えだと思いますが、わかりません。あなたが私に同意しない場合、チャットで私にpingを送信します。
ハイパーニュートリノ

1
The input will be valid so that the solutions of x are not saddle points、ケース[1,0,0,3]は点を与えているようです。
ジョンファンミン

1
@JungHwanMinああ、その例はルールが作成される前に追加されました。削除されました。
マニッシュクン

1
x^3 - 12x^2 + 45x + 8 = 0個人的に私が好むが、あなたはとしてそれを書くf(x)=x^3-12x^2+45x+8ことなく、=0なぜなら=0私たちは方程式を解くことではない、機能を扱っているので、意味がありません。
周jun順

回答:


4

ゼリー、20バイト

ASŒRḅ@Ðḟ
J’U×µṖÇḅ@€³

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

説明

ASŒRḅ@Ðḟ     Helper Function; find all integer solutions to a polynomial
             All integer roots are within the symmetric range of the sum of the absolute values of the coefficients
A            Absolute Value (Of Each)
 S           Sum
  ŒR         Symmetric Range; `n -> [-n, n]`
      Ðḟ     Filter; keep elements where the result is falsy for:
    ḅ@       Base conversion, which acts like the application of the polynomial
J’U×µṖÇḅ@€³  Main Link
J                             Range of length
 ’                    Lowered
  U          Reversed
   ×         Multiplied with the original list (last value is 0)
    µ        Begin new monadic chain
     Ṗ       Pop; all but the last element
      Ç      Apply last link (get all integer solutions of the derivative)
       ḅ@€³  Base conversion of the polynomial into each of the solutions; apply polynomial to each solution of the derivative.

このプログラムのヘルパー機能は、Xcoder氏の回答から取られ ました。これはLuisの回答に基づいています。


@JungHwanMin OPにそれを指摘します。これは、の多項式の導関数がであるためaddle点がないというステートメントの直接違反3です0編集ああすでにNVMちょうどそのコメントをupvotedなかった
HyperNeutrino

3

JavaScriptの(ES7)、129の 120バイト

係数を累乗順に取得します。

a=>(g=x=>x+k?(A=g(x-1),h=e=>a.reduce((s,n,i)=>s+n*(e||i&&i--)*x**i,0))()?A:[h(1),...A]:[])(k=Math.max(...a.map(n=>n*n)))

テストケース

コメント済み

a => (                        // given the input array a[]
  g = x =>                    // g = recursive function checking whether x is a solution
    x + k ? (                 //   if x != -k:
      A = g(x - 1),           //     A[] = result of a recursive call with x - 1
      h = e =>                //     h = function evaluating the polynomial:
        a.reduce((s, n, i) => //       for each coefficient n at position i:
          s +                 //         add to s
          n                   //         the coefficient multiplied by
          * (e || i && i--)   //         either 1 (if e = 1) or i (if e is undefined)
          * x**i,             //         multiplied by x**i or x**(i-1)
          0                   //         initial value of s
        )                     //       end of reduce()
      )() ?                   //     if h() is non-zero:
        A                     //       just return A[]
      :                       //     else:
        [h(1), ...A]          //       prepend h(1) to A[]
    :                         //   else:
      []                      //     stop recursion
  )(k = Math.max(             // initial call to g() with x = k = maximum of
    ...a.map(n => n * n)      // the squared coefficients of the polynomial
  ))                          // (Math.abs would be more efficient, but longer)

1
以下のために失敗した0,0,1(X ^ 2 = 0)
betseg

@betsegこれを報告してくれてありがとう。修繕。
アーナウルド

3

Julia 0.6Polynomialsパッケージ付き)、57バイト

using Polynomials
x->map(Poly(x),roots(polyder(Poly(x))))

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

係数を昇順で受け取ります。つまり、最初の入力は定数項です。

実行例:

julia> using Polynomials

julia> g = x -> map(Poly(x), roots(polyder(Poly(x))))
(::#1) (generic function with 1 method)

julia> g([8,45,-12,1])
2-element Array{Float64,1}:
 58.0
 62.0

3

Java 8、364 239 227 226 218バイト

a->{int l=a.length,A[]=a.clone(),s=0,i,r,f=l,p;for(;f>0;A[--f]*=f);for(int n:A)s+=n<0?-n:n;for(r=~s;r++<s;){for(p=0,i=f=1;i<l;f*=r)p+=A[i++]*f;if(p==0){for(f=i=0;i<l;f+=a[i++]*Math.pow(r,p++));System.out.println(f);}}}

私のこの答えと同じ機能を使用します。

@OlivierGrégoireのおかげで、配列の順序が逆になり、-8バイトになりました。

説明:

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

a->{                  // Method with integer-varargs parameter and integer return-type
  int l=a.length,     //  The length of the input-array
      A[]=a.clone(),  //  Copy of the input-array
      s=0,            //  Sum-integer, starting at 0
      i,              //  Index-integer
      r,              //  Range-integer
      f=l,            //  Factor-integer, starting at `l`
      p;              //  Polynomial-integer
  for(;f>0;           //  Loop over the copy-array
    A[--f]*=f);       //   And multiply each value with it's index
                      //   (i.e. [8,45,-12,1] becomes [0,45,-24,3])
  for(int n:A)        //  Loop over this copy-array:
    s+=n<0?-n:n;      //   And sum their absolute values
  for(r=~s;r++<s;){   //  Loop `r` from `-s` up to `s` (inclusive) (where `s` is the sum)
    for(p=0,          //   Reset `p` to 0
        i=f=1;        //   and `f` to 1
                      //   (`i` is 1 to skip the first item in the copy-array)
        i<l;          //   Inner loop over the input again, this time with index (`i`)
        f*=r)         //     After every iteration: multiply `f` with the current `r`
      p+=             //    Sum the Polynomial-integer `p` with:
         A[i++]       //     The value of the input at index `i`,
               *f;}   //     multiplied with the current factor `f`
    if(p==0){         //   If `p` is now 0:
      for(f=i=0;      //    Use `f` as sum, and reset it to 0
          i<l;        //    Loop over the input-array
        f+=a[i++]*Math.pow(r,p++));
                      //     Fill in `r` in the parts of the input-function
      System.out.println(f);}}}
                      //    And print the sum

2
1,0,0(x ^ 2 = 0)で失敗
-betseg

@betsegありがとう!固定およびゴルフ。
ケビンクルーッセン

1
次のようにカウントを減らすには、入力を逆の順序(明示的に許可されている)で受け入れる必要がありますint... ,i, ...; for(;f>0;)A[--f]*=f;。誤解がない限り、これで少なくとも4バイト節約できます。これを行う場合は、入力へのすべてのアクセスを必ず反転させてください。
オリビエグレゴワール

@OlivierGrégoireありがとう、8バイト保存されました!
ケビンクルーイッセン





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