NをM個の整数の積として書く方法はいくつありますか?


12

整数Nが与えられた場合、M整数> 1の積として表現できる方法の数をカウントします。

入力は単純にNおよびMであり、出力は個別の整数グループの総数です。つまり、整数を複数回使用できますが、各グループは別個でなければなりません(存在する3 x 2 x 2場合2 x 2 x 3はカウントされません)。

制約

1 < N <2 31
1 < M <30

入力30 233つの方法で表現できるため、outputを提供します。

2 x 15
3 x 10
5 x 6

入力16 3はoutputを提供します。これは1、異なるグループが1つしかないためです。

2 x 2 x 4

入力2310 4は出力を与えます10

5 x 6 x 7 x 11
3 x 7 x 10 x 11
3 x 5 x 11 x 14
3 x 5 x 7 x 22
2 x 7 x 11 x 15
2 x 5 x 11 x 21
2 x 5 x 7 x 33
2 x 3 x 11 x 35
2 x 3 x 7 x 55
2 x 3 x 5 x 77

入力15 40、実行できないため、出力を提供します。

ルール

標準コードのゴルフの抜け穴が、入出力の標準定義とともに適用されます。回答は、機能または完全なプログラムの場合があります。因数分解や分割のための組み込み関数は許可されていませんが、他の関数は問題ありません。コードはバイト単位でカウントされます。


パーティション分割とはどういう意味ですか?
オプティマイザー

@Optimizerリストを重複しないサブリストにグループ化します。Mathematicaなど、一部の言語にはこれが組み込まれています。
ジオビット

制限時間はありますか?特に単純なアルゴリズムは、Mの値が大きい場合は何世紀もかかる可能性があります。sqrt(N)よりも1因子だけ大きいことに注意するなどの単純なことは、明らかに役立ちます。
レベルリバーセント

1
@steveverrill Nの上限を考えると、最大で30(素数)の因子しかありません。これにより、処理がかなり高速になります。ただし、気軽に素朴になってください。アルゴリズムが数時間以内に答えを提供する可能性が低い場合、十分に説明された概念実証が有権者の決定に役立ちます。
ジオビット

2つのリストのデカルト積を実行できるビルトインは許可されていますか?
オプティマイザー

回答:


5

Pyth - 24 23 22 21バイト

複雑な解決策ではありません。もっとゴルフをします。リストとフィルターのデカルト積を取ります。@optimizerと同じ戦略(私は彼のコメントのために推測していますが、実際にはCJamを解読しませんでした)@FryAmTheEggmanに2バイト感謝し、Mでトリックします。

Ml{m`Sdfqu*GHT1G^r2GH

関数を定義g引数とGし、H

M                    function definition of g with args G and H
 l                   length of
  {                  set (eliminates duplicates)
   m                 map
    `Sd              repr of sorted factors so can run set (on bash escape ` as \`)
    f                filter
     q      G        equals first arg
      u*GHT1         reduce by multiplication
     ^     H         cartesian product by repeat second arg
       r2G           range 2 to first arg

最後を除くすべてのテスト引数で作業しましたが、そのテスト引数では遅すぎましたが、時間制限はありません。


その形式では入力は問題ありません。
ジオビット

1
Pythゴルフのヒント:2つの引数を取得する場合、通常は2つの引数Mの関数を定義する使用する方が短くなります。これは私がこれのために得るものです:。別のPythユーザーに会えていつも嬉しいです:)gGHMl{msdfqu*GHT1G^r2GH
FryAmTheEggman

@FryAmTheEggmanは、ヒントをありがとう。
マルティセン

1
これは、72 35を返す入力に対して誤った答えを与えるようですが、実際には6つの答えがあります。(2, 2, 18), (2, 3, 12), (2, 4, 9), (2, 6, 6), (3, 3, 8)
isaacg

1
@isaacgわかりました、21文字バージョンに戻します。集計してもうまくいくとは思いませんでしたが、どうやらそうだったので、reprに戻ります。キャッチしてくれてありがとう。
マルティセン

9

Python 3、59

f=lambda N,M,i=2:i<=N and f(N/i,M-1,i)+f(N,M,i+1)or-~M==N<2

潜在的な除数を数えますi。追加の引数iを最小許容除数として使用すると、コアの再帰的関係は

f(N,M,i)=f(N/i,M-1,i)+f(N,M,i+1)

それぞれiに対して、それを含めることを選択します(繰り返しとして可能)。その場合、必要な製品をで除算Ni、減分しますM。そうでないi場合i<N、1だけ増加しますが、の場合のみですN

最小約数iがを超えるとN、潜在的な約数はなくなります。我々があれば見て成功してきたのであれば、我々はチェックしM==0 and N==1、または、同等、M+1==N==1またはM+1==N<2とき以来、M+1==N相互の値が正の整数(この最適化のためのFryAmTheEggmanのおかげで)であることが保証され、。

このコードにより、スタックオーバーフローが発生します。 Nほとんどのシステムで約1000のこれを回避するにはStackless Pythonで実行できます。さらに、指数関数的な再帰分岐のため、非常に低速です。


使用できると思います-~M==N<2
-FryAmTheEggman

@FryAmTheEggman私はそれが偽陽性を与えるだろうと思ったが、確かにそれは、上の関節拘束のおかげで働くMとをN。ありがとう!
xnor

4

ルビー、67

f=->n,m,s=2,r=0{m<2?1:s.upto(n**0.5){|d|n%d<1&&r+=f[n/d,m-1,d]}&&r}

再帰的な定義に対して実際には合理的に効率的です。[d,q]nの除数ペアごとdに、小さい方で、の結果を合計しf[q,m-1]ます。トリッキーな部分は、内側の呼び出しで、係数をd以上に制限して、二重カウントにならないようにすることです。

1.9.3-p327 :002 > f[30,2]
 => 3 
1.9.3-p327 :003 > f[2310,4]
 => 10 
1.9.3-p327 :004 > f[15,4]
 => 0 
1.9.3-p327 :005 > f[9,2]
 => 1 

2

CJam、48バイト

これははるかに短くなる可能性がありますがM、オンラインコンパイラで適切な数で動作するように特定のチェックを追加しました。

q~\:N),2>{N\%!},a*{_,2/)<m*{(+$}%}*{1a+:*N=},_&,

こちらからオンラインでお試しください


これはバグです。入力してみてください2 1。予想される出力:1.実際の出力:0
ピーター・テイラー

@PeterTaylorため息。修繕。
オプティマイザー

2

T-SQL 456 373

入力が大きくなりそうになると、これは壊れるはずです。

@MickyTに感謝します。複数のSETの代わりにCONCATとSELECTを使用して多くの文字を保存できます。

CREATE PROC Q(@N INT,@M INT)AS
DECLARE @ INT=2,@C VARCHAR(MAX)='SELECT COUNT(*)FROM # A1',@D VARCHAR(MAX)=' WHERE A1.A',@E VARCHAR(MAX)=''CREATE TABLE #(A INT)WHILE @<@N
BEGIN
INSERT INTO # VALUES(@)SET @+=1
END
SET @=1
WHILE @<@M
BEGIN
SELECT @+=1,@C+=CONCAT(',# A',@),@D+=CONCAT('*A',@,'.A'),@E+=CONCAT(' AND A',@-1,'.A<=A',@,'.A')END
SET @C+=CONCAT(@D,'=',@N,@E)EXEC(@C)

これに賛成したいのですが、テストする簡単な方法が見つかりません。何か案は?動作することのサードパーティの確認も良いです。
ジオビット

実行すると、いくつかの変換エラーが発生します(2012)。それらはこれらの声明からのものSET @C+=',# A'+@と思われますSET @D+='*A'+@+'.A'SET @E+=' AND A'+(@-1)+'.A<=A'+@+'.A'
-MickyT

また、修正する必要がありますSET @C+=@D+'=@N'+@E+' SELECT @'@Nあなたは、実行時に範囲外のそれを作る引用符の内側にあります@C。また、重複を数えることになります
-MickyT

今、2012年にテストしました。動作するはずです。
bmarks

2
うまく動作するようになりました:)いくつかのキャラクターを剃ることができるいくつかの場所。を使用CONCATして文字列を作成してみてください。その後、CONVERTs をドロップできます。ループで試しSELECT @+=1,@C+=CONCAT(...),@D+=CONCAT(...),@E+=CONCAT(...)てくださいWHILE。合理的な数を保存する必要があります
MickyT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.