nのべき乗を合計します


14

行き方

入力整数nn >= 0)が与えられると、最小の正の整数 mを出力するプログラムを作成します。ここで、

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • abは、同じ長さの有限シーケンスです
  • すべての要素は、a以下でありますm
  • すべての要素は、b以下でありますm
  • のすべての要素a異なり、整数ですa[x] >= 0
  • のすべての要素b異なり、整数ですb[x] >= 0
  • a[x]またb[x]、両方とも0ではありません(0 ^ 0は不確定であるため)

これはなので、バイト数が最も少なくなります。

In 0 -> Out 1
Possible Sum: 

In 1 -> Out 2
Possible Sum: 1^0

In 2 -> Out 3
Possible Sum: 2^1

In 3 -> Out 3
Possible Sum: 2^1 + 1^0

In 6 -> Out 4
Possible Sum: 2^2 + 3^0 + 1^1

In 16 -> Out 5
Possible Sum: 2^4

In 17 -> Out 4
Possible Sum: 3^2 + 2^3

In 23 -> Out 6
Possible Sum: 5^1 + 3^0 + 2^4 + 1^3

In 24 -> Out 5
Possible Sum: 4^2 + 2^3

In 27 -> Out 4
Possible Sum: 3^3

In 330 -> Out 7
Possible Sum: 6^1 + 4^3 + 3^5 + 2^4 + 1^0

無限の合計を持たない一意の非負の整数のシーケンスを作成する方法を教えてください。
feersum

また、最初のケースは意味がありません。0項の合計で十分だからです。
feersum

@feersum私はあなたの質問をよく理解していません。これに対する私の解決策は、等しい合計を見つけるまでm<2m<3then m<4などのすべての組み合わせのブルートフォース検索ですn。また、合計を無条件にする0ことを考えましたが、出力はどうなりますか?m>?
kukac67

1
有限シーケンスの場合、通常は次のようになりn = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k]ます。
ボラティリティ

1
いい質問です。最初のテストケースでは1つだけです:abは、長さの有限シーケンスであるため、制約を満たさ0ない整数mはなく、最小の整数がないため、答えは定義されていません。可能な修正方法は、最小の自然数m(この場合、予想される答えをそこに変更する必要があります0)または最小の正の整数を求めることmです。
ピーターテイラー

回答:


2

GolfScript(59文字)

~:T),{),.0{2$0-{2${{4$2$^}2*@3$\?4$+f~}%\;~}%+\;\;}:f~T&}?)

オンラインデモ

これは、再帰を使用して、特定の達成可能な値を列挙し、動作mする最初の値を検索しmます。xnorの答えに少し触発されていますが、実装はまったく異なります。

解剖

~:T                  # Evaluate input and store in T (for Target)
),{                  # Search [0 1 ... T] for the first m which matches a predicate
  ),.0               #   Push [0 ... m] to the stack twice and then 0
                     #   Stack holds: possibleAs possibleBs sum
  {                  #   Define the recursive function f
    2$0-{            #     Map over A in possibleAs (except 0)
      2${            #       Map over B in possibleBs (except 0)
        {4$2$^}2*    #         Duplicate respective possibles and remove selected values
        @3$\?4$+     #         Compute sum' = sum + A^B
        f            #         Recursive call gives an array [sums]
        ~            #         Push the sums to the stack individually
        }%           #       End map: this collects the sums into a combined array
      \;             #       Pop A, leaving just the combined [sums] inside the map
      ~              #       Repeat the trick: push to the stack individually
    }%               #     End map, collecting into a combined array
                     #     Stack now holds: possibleAs possibleBs sum [sums]
    +                #     Include the original sum in the array of reachable sums
    \;\;             #     Pop possibleAs and possibleBs
  }:f                #   End function definition
  ~                  #   Evaluate the function
  T&                 #   Test whether the sums contain T
}?                   # End search
)                    # Increment to get m

6

Python、120

f=lambda n,A,B:n*all(f(n-a**b,A-{a},B-{b})for a in A for b in B)
g=lambda n,m=1,M={0}:f(n,M-{0},M)and g(n,m+1,M|{m})or m

この関数fは、からの異なる基数とからの指数を持つ累乗の和として表現nできないかどうかをチェックする補助関数です。それは自然な再帰的戦略を使用します:ゼロ以外でなければならず、ベースと指数のあらゆる可能な選択を試みますが、それらはすべて失敗する必要があります。それらを許可リストから削除し、対応する量だけ減らします。ABnn

関数gはメイン関数です。動作するものを検索しますmMは、までの許容値のセットですm-1。(Pythonが1と評価する)使用されるの0を止めるために、許可された指数から削除し0**0ます。これは何も傷つけません。他のすべてに0**xは役に立たないからです。0x


あなたは、おそらく変更される可能性n and all()n*all()
-grc

@grcああ、あなたは実際にショートサーキットを必要としません。改善してくれてありがとう。
-xnor

4

Python 2、138バイト

from itertools import*
S=lambda n,m=0,R=[]:m*any(n==sum(map(pow,*C))for k in R for C in product(*tee(permutations(R,k))))or S(n,m+1,R+[m])

(すべてのヒントを@Jakubeに感謝します)

itertoolsこの1つの質問から、モジュールについてあまり学んだことがありません。最後のケースには約1分かかります。

m = 1解決策が見つかるまで、検索して増分することから始めます。解決策を確認するには、繰り返し処理します。

  • k = 0 to m-1、ここでkはソリューション内の用語の数です
  • 用語のすべての可能な組み合わせ([0, 1, ... m-1]sizeののサブセットの2つの順列を一緒に圧縮することによりk)、次に、n

反復することに注意してください kまでm-1-にもかかわらず、技術的m観点からは、合計で可能であり、と解決策は常にありますm-1よう用語は0^0許されず、0^b何も寄与しません。0^0Pythonによって1として扱われるため、これは実際に重要です。これは問題のように見えますが、問題ではないことが判明しました。

その理由は次のとおりです。

誤って見つかった解決策が使用すると仮定します 0^0て1としてれる3^2 + 1^1 + 0^0 = 11。最大でm-1用語を生成するだけなのでj、ベースとして使用していないものがいくつかあるはずです(こちらj = 2)。j有効なソリューションを得るために、ここでベース0を交換できます3^2 + 1^1 + 2^0 = 11

すべてのm用語まで反復した場合、m = 2for n = 20^0 + 1^1 = 2


良いですね。ただし、imapを使用して4バイトを節約できます。 imap(pow,C,D) ... for C,D in
ジャクベ

@Jakube私は実際に私がitertools話すようにドキュメントを探しています:PIはすでに別の節約をしています— tee
Sp3000

私も。また、私の間違い。なぜ誰かが提案imapするのですmapか?-1バイト
ジャクベ

のデフォルトパラメータteeはすでにn=2です。2バイト節約します。
ジャクベ

@Jakube Ahahaありがとう。これはおそらく、map複数の反復可能オブジェクトを使用したのは初めてのことであり、実際、この質問は私にとって多くの最初のものをもたらします。
Sp3000

4

GolfScript(90 84バイト)

[0.,.]](~:T),(+{:x;{:|2,{:c)|=x),^{c[1$x]=:A^x^:-;[|~-+@A-?+@A+@]}%}/+~}%.[]*T&}?)\;

オンラインデモ

解剖

[0.,.]             # Base case: [sum As Bs] is [0 [] []]
](~:T              # Collect it in an array of cases; fetch parameter, eval, store in T.
),(+               # Create array [1 2 ... T 0]. Putting 0 at the end means that it won't
                   # be reached except when T is 0, and nicely handles that special case.
{                  # Loop over the values from that array...
  :x;              #   ...assigning each in turn to x (and popping it from the stack)
  {                #   Stack holds array of [sum As Bs] cases; map them...

    :|             #     Store [sum As Bs] in |
    2,{:c          #     For c in [0 1]...
      )|=x),^      #       Get [0 1 ... x]^ either As or Bs, depending on c
      {            #       Map these legal new As or Bs respectively...
        c[1$x]=:A  #         Work out which of that value or x is the new A
        ^x^:-;     #         And the other one is the new B
        [          #         Begin gathering in an array
          |~       #           Push sum As Bs to the stack
          -+       #           Add - to Bs to get Bs'
          @A-?+    #           Rotate sum to top and add A^- to get sum'
          @A+      #           Rotate As to top and add A to get As'
          @        #           Final rotation to put elements in the right order
        ]          #         Gather in array [sum' As' Bs']
      }%           #       End map
    }/             #     End for
    +~             #     Push all the elements corresponding to x^B and A^x on to the stack
  }%               #   End map, collecting the untouched [sum As Bs] and all the new
                   #   [sum' As' Bs'] arrays into a new array of reached cases.
  .[]*T&           #   Flatten a copy of that array and filter to values equal to T.
                   #   This gives a truthy value iff we've found a way to make T.
}?                 # Loop until we get a truthy value, and push the corresponding x
)\;                # Increment to get the value of m and discard the array of cases

最もエレガントなトリックは、の特殊なケースの処理です0


CJamが今回は標準のpython = Pよりもそれほど短くないことを本当に嬉しく思います
-flawr

@flawr、これはCJamではなくGolfScriptです。CJamは、デカルト製品用の組み込み機能を備えているため、おそらくかなり短くなる可能性があります。また、再帰関数のxnorのアイデアは、より短いGolfScriptを提供する可能性もあります。
ピーターテイラー

ああ、ごめんなさい、ただ混乱させただけ=)
flawr

4

ハスケル、143 130

import Data.List
p n=head$[1..]>>=(\m->[m|let x=permutations[0..m-1]>>=inits,a<-x,b<-x,sum(zipWith(\x y->x^y*signum(x+y))a b)==n])

使用例:p 23-> 6

これは単純なブルートフォース検索です。すべてのリストについて[0..0], [0..1], [0..2] ... [0..∞]、順列のすべての初期セグメントを取得します(例[0..2]:permutations:、[012], [102], [210], [120], [201], [021]最初の順列の初期セグメント:[0], [01], [012]、2nd:[1], [10], [102]など)。これらのリストの2つの組み合わせごとに、べき乗の合計を計算します。最初の値がnになったら停止します。


あなたは使うべき>>=ではなくconcatMap。それらはまったく同じですが、引数が反転しています。
誇りに思ってhaskeller

@proudhaskeller:はい、ありがとう!
nimi

2

Python:166文字

from itertools import*;p=permutations
f=lambda n,r=[0]:any(n==sum(map(lambda x,y:(x+y>0)*x**y,a,b))for j in r for a,b in product(p(r,j),p(r,j)))*1or 1+f(n,r+[len(r)])

説明

この関数fは、可能な整数をすべて作成しrます。これは、の数値の累乗の合計として表現できます。で始まる場合r = [0]。これらの整数のいずれかがに等しい場合n、の長さを返しますr。それ以外の場合、拡張されたr

合計として表現できるすべての整数の計算は、2つのループで実行されます。最初のループはfor j in rで、式の長さを示します(2 ^ 3 + 1 ^ 2の長さは2です)。内側のループはr、length の順列のすべての組み合わせを反復処理しますj。それぞれについて、パワーの合計を計算します。


2

JavaScript(ES6)219 224

再帰関数。m = 1から始めて、整数1..mの基底と指数の0..mのすべての組み合わせを試してみます(0基底は0 ^ 0 == undefinedの場合は役に立ちません)。
解が見つからない場合は、mを増やして再試行してください。
入力0の特別な場合(とにかく仕様のエラーです)

C関数は、指定された長さの配列からすべての組み合わせを再帰的に生成するため、

C(3, [1,2,3]) --> [[3,2,1], [3,1,2], [2,3,1], [2,1,3], [1,3,2], [1,2,3]]

3番目のレベルeveryは、基底の配列aと指数の配列bを一緒に圧縮するために使用されます(zipJavaScript には関数はありません)。every2つの配列内のすべての要素を使用しない解決策がある場合、早期に停止するために使用します。

F=(n,j=1,k=[],
  C=(l,a,o=[],P=(l,a,i=l)=>{
    for(l||o.push(a);i--;)
      e=[...a],P(l-1,e.concat(e.splice(i,1)))
  })=>P(l,a)||o
)=>n&&C(k.push(j++),k)[E='every'](a=>C(j,[0,...k])[E](b=>a[E](x=>t-=Math.pow(x,b.pop()),t=n)))
?F(n,j,k):j

FireFox / FireBugコンソールでテストする

;[0,1,2,3,6,16,17,23,24,27,330].map(x=>[x,F(x)])

出力

[[0、1]、[1、2]、[2、3]、[3、3]、[6、4]、[16、5]、[17、4]、[23、6]、[ 24、5]、[27、4]、[330、7]]

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