数値が連続した整数の積であるかどうかを確認します


18

以下に示すように、6、12、20、30、42、56、60、90、120などのいくつかの数字は、連続する整数の積として表現できます。

6   = 2 * 3  
12  = 3 * 4  
30  = 5 * 6
60  = 3 * 4 * 5  
90  = 9 * 10  
120 = 4 * 5 * 6  

指定した数に等しい積の連続した整数のリストを出力するプログラムまたは関数を作成します。

このロジックに適合しない数値の例は次のとおりです。

99  = 9 * 11  (Product of non-consecutive numbers)
121 = 11 * 11 (Same numbers)
2   = 1 * 2   (Product of itself and 1)
13  = 13      (Product of only one number)

の場合2 = 2 * 1、整数を1倍すると同じ結果が得られるため、有効な結果とは見なされないことに注意してください。この質問では、製品では2以上の整数のみを考慮します。

入力

有効な32ビットの正の整数。標準入力、関数引数などから取得できます。

出力

2以上の連続した整数のリスト(昇順または降順)。連続する整数の組み合わせが複数ある場合は、1つのインスタンスを提供するだけです。さらに提供する場合は、罰金です。

制限事項

コードは、標準のコンピューターで実行するのに妥当な時間(<5分)かかります、すべての有効な入力(正の32ビット整数)に対してでます。連続する整数積がある場合、コードは制限時間内に1つ以上を出力する必要があります。そうでない場合、コードは制限時間内に出力なしで終了するはずです。

これはコードゴルフであるため、バイト単位の最短コードが優先されます。


1
述べられているように、このパズルはこのサイトの形式には適していません。このサイトは、勝者を決定する良い方法があるコンテストのためのものです(例えば、最短のコード、最速のコード、ほとんどの賛成票など)。あなたはそのような方法を提供していません。
クリスジェスターヤング

2
ただし、これをコードゴルフ(最短コード)にすることをお勧めします。ただし、制限を加える必要があります。たとえば、0〜1000000の数字、最大実行時間10秒など
Level River St

この質問を救うためにそれを編集しようとしました。しかし、私は以前に質問をしていないので、もし何かを見るならば、編集してください。
ベクトル化

@bitpwnerいくつかのタイプミスはさておき、私には問題ないようです。再開に投票しました。
seequ 14

5
あなたが意味すると思います30=5*6
カイルカノス14

回答:


8

Java-124

String f(int t){int s=2,h=3,p=s,i;String o="";for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);if(p==t)for(i=s;i<h;o+++=i+" ");return o;}

2から開始し、開始番号がターゲットの平方根(またはターゲットに正確に達する)になるまでループします。製品が低い場合、高い数で乗算し、増分します。高い場合は、開始番号で除算して増分します。

たとえば、30の場合、次のことを確認します。

2*3     = 6 (too low, multiply)
2*3*4   = 24 (too low, multiply)
2*3*4*5 = 120 (too high, divide)
3*4*5   = 60 (too high, divide)
4*5     = 20 (too low, multiply)
4*5*6   = 120 (too high, divide)
5*6     = 30 (bingo!)

スペースで区切られた因子の文字列を昇順で出力します。

改行あり:

String p(int t){
    int s=2,h=3,p=s,i;
    String o="";
    for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);
    if(p==t)
        for(i=s;i<h;o+=i+" ");
    return o;
}

7

Python- 104 97 95 92 試してみる

n=input()
s=i=2
c=1
while s<n:
 s*=i+c;c+=1
 if s==n:print range(i,i+c)
 if s/n:i+=1;s,c=i,1

nたとえば、事前に120に設定されている場合、プログラムは次の2つのソリューションを出力します。

[2, 3, 4, 5]
[4, 5, 6]

申し訳ありませんが、入力を定義するのを忘れました。
ファルコ14

1
c = c + 1、i = i + 1をc + = 1、i + = 1に置き換える
Gerrat

1
そうそう、考えていませんでした+=。しかし、私のミス++Pythonで...
ファルコ

1
if s>=nif s/n同等であるため、すべてのソリューションを同じ文字数で提供できます。
isaacg 14

1
に変更s=s*(i+c)すると、3文字を保存できますs*=i+c
エレンディアスターマン14

4

Clojure- 127の 109バイト

(defn f[x](first(for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v)))

例:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> ((2 3) (3 4) (5 6) (3 4 5) (9 10) (2 3 4 5) (111 112 113) nil nil nil nil)

説明:

これは基本的な、まったく最適化されていない機能的アプローチです。私はそれらの単純なループを使用してすべての可能性の怠zyなリストを作成し(大きすぎる数を与えるすべての組み合わせをスキップしてオーバーフローを防ぎます)、それらの最初を取得します。可能性がない場合、nilを返します。

http://tryclj.com/でテストするのが最も簡単です。


また、120バイト 102バイトのすべての可能性を返すことができることに気付きましたが、ネストされたリストで結果を提供します。

(defn f[x](for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v))

例:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> (((2 3)) ((3 4)) ((5 6)) ((3 4 5)) ((9 10)) ((2 3 4 5) (4 5 6)) ((111 112 113)) () () () ())

3

CJam、31バイト

q~:Qmq,A,m*{2f+~,f+_:*Q={p}*}%;

それはブルートフォースアプローチですが、公式のJavaインタープリターを使用すると実行時間はわずか数秒ですです。

オンラインインタープリターを使用してコードをテストする場合は、入力をかなり低く保つ必要があります。2 26未満まだ私のマシンで動作します。

$ TIME="%e s"
$ time cjam product.cjam <<< 2
0.12 s
$ time cjam product.cjam <<< 6
[2 3]
0.10 s
$ time cjam product.cjam <<< 120
[2 3 4 5]
[4 5 6]
0.12 s
$ time cjam product.cjam <<< 479001600
[2 3 4 5 6 7 8 9 10 11 12]
0.68 s
$ time cjam product.cjam <<< 4294901760
[65535 65536]
1.48 s
$ time cjam product.cjam <<< 4294967295
1.40 s

使い方

q~:Q      " Read from STDIN, interpret the input and save the result in variable “Q”.     ";
mq,       " Push the array [ 0 1 2 … (Q ** 0.5 - 1) ].                                    ";
A,m*      " Push the array [ 0 1 2 … 9 ] and take the Cartesian product.                  ";
{         " For each pair in the Cartesian product:                                       ";
  2f+     " Add 2 to each component.                                                      ";
  ~       " Dump the array's elements on the stack.                                       ";
  ,       " Push the array [ 0 1 2 … n ], where “n” is the topmost integer on the stack.  ";
  f+      " Add “m” to each element, where “m” is the integer below the array.            ";
  _:*     " Duplicate the resulting array and push the product of its elements.           ";
  Q={p}*  " If the product is equal to “Q”, print.                                        ";
}%        " Collect the remaining results into an array.                                  ";
;         " Discard the array from the stack.                                             ";

2

Java、162

整数の配列を返すかnull、連続する番号が存在しない場合。

int[] e(int n){for(int i=1;i<n;i++){int h=i+1,c=1,s=i;while(s<n){c++;s*=h++;}if(s==n){int[] o=new int[c];for(int j=0;j<c;j++){o[j]=h-j-1;}return o;}}return null;}

なし:

int[] execute(int input){
    for(int i=1; i<input; i++){
        int highest = i+1, count = 1, sum = i;
        while(sum < input){
            count++;
            sum *= highest++;
        }
        if(sum == input){
            int[] numbers = new int[count];
            for(int j=0; j<count; j++){
                numbers[j] = highest-j-1;
            }
            return numbers;
        }
    }
    return null;
}

2

C 105 110 試してみる

n,k,l;main(i){for(scanf("%d",&n);++i<n;)for(k=1,l=i;k<n;)if(k*=l++,k==n)for(l=n;l/=i;)printf("%d ",i++);}

144ボーナス付き:これはすべての番号を反復処理し、一致する製品を見つけます

main(i,j,k,l,m){for(scanf("%d",&m);++i<13;)for(j=0;++j<46341-i;){for(l=k=1;k<=i;)l*=j+k++;if(l==m)for(puts(""),k=0;k<i;)printf("%d ",j+k+++1);}}

素敵で、とてもシンプルでエレガント!私が投げた小さな数字のいくつかで間違いなく働いた。それから50815512(7128 x 7129)を与えると、無限ループに入りました。7128 x 7129 x 7130 = 362314600560を計算しようとするとオーバーフローしますか?
トッドリーマン14

ありがとう!どうやらのために状態k < nが高すぎk *= l++ます。私は人生を台無しに始めたが...にunsigned long long型APPEND可能性
BEBE

2

PHP 258文字、201は階乗関数をカウントしません。

「数値に等しい連続した要因」を数学的に表現する最も簡単な方法は、X!/Y!Where Xが最高の数でY、最低が1を引いたものです。残念ながら、解く前に微積分をやめたZ = X!/Y!ので、少し強引にならなければなりませんでした。

乱雑な、無料版:

<?php
// PHP does not define a factorial function, so I've kludged one in.
function fact($n) {
    $r = 1;
    for($i=$n; $i>1; $i--) {
        $r *= $i;
    }
    return $r;
}

$input = intval($argv[1]);

if( $input < 2 ) { die('invalid input'); }

printf("input: %s\n", $input);

$max=min(ceil(sqrt($input)),170); // integer breakdown for > 170!
$grid = array();
for( $x=1;$x<$max;$x++ ) {
    for( $y=$max;$y>=1;$y-- ) {
        if( $y >= $x ) { continue; } // Skip results that would be < 1
        $cur = fact($x)/fact($y);
        if( $cur > $input ) { // too large!
            echo "\n"; continue 2;
        }
        if( $cur == $input ) { //just right
            printf("%7d\n\nFound %s == %s\n", $cur, implode(' * ', range($y+1, $x)), $cur);
            break 2;
        }
        printf("%7d ", $cur);
    }
    echo "\n";
}
if($cur!=$input){printf("No consecutive factors produce %d\n", $input);}

出力例:

input: 518918400

  2
  3       6
  4      12      24
  5      20      60     120
  6      30     120     360     720
  7      42     210     840    2520    5040
  8      56     336    1680    6720   20160   40320
  9      72     504    3024   15120   60480  181440  362880
 10      90     720    5040   30240  151200  604800 1814400 3628800
 11     110     990    7920   55440  332640 1663200 6652800 19958400 39916800
 12     132    1320   11880   95040  665280 3991680 19958400 79833600 239500800 479001600
 13     156    1716   17160  154440 1235520 8648640 51891840 259459200
 14     182    2184   24024  240240 2162160 17297280 121080960
 15     210    2730   32760  360360 3603600 32432400 259459200
 16     240    3360   43680  524160 5765760 57657600 518918400

Found 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 == 518918400

ゴルフ:

<? function f($n){$r=1;for($i=$n;$i>1;$i--)$r*=$i;return $r;}$i=$argv[1];$m=min(ceil(sqrt($i)),170);for($x=1;$x<$m;$x++){for($y=$m;$y>0;$y--){if($y>=$x)continue;$c=f($x)/f($y);if($c>$i)continue 2;if($c==$i){$y++;echo "$y $x";break 2;}}}if($c!=$i){echo 'No';}

出力:

[sammitch@vm ~/golf] time php consecutive_golf.php 518918400
9 16
real 0m0.019s
user 0m0.011s
sys  0m0.009s
[sammitch@vm ~/golf] time php consecutive_golf.php 518918401
No
real 0m0.027s
user 0m0.017s
sys  0m0.011s

実行時間がこれほど速くなるとは思っていませんでした!


このアイデアも思い浮かび、非常に効率的に見えますが、「資格を得るために」十分に短縮できるとは思いません。
ベベ14

1
@bebeは258文字で、PHPにとっても悪くありません。怠け者で頑固でなければ、本当の言語でやります。:P
Sammitch 14

X!/ Y!Y <N <= Xとなる整数Nの積です。それはまったく役に立ちますか?
センモウヒラムシ

2

ピス、35

JvwKr2 4W-ZJ~@KgJZ1=YurGHK=Zu*NTY)Y

注:私のコードは実際に入力の最短表現を2以上の連続する整数の表現として見つけます。したがって、無効な入力では、おそらく非常に長い時間の後に1要素のリストを出力します。問題のステートメントは入力が有効になると言っているので、これは問題ないと思います。

簡単な説明:

基本的に、プログラムは範囲の上限と下限を保存し、reduceを使用して範囲内の数値の積を計算し、必要に応じてエンドポイントを調整し、積が入力と等しくなるまで繰り返します。

長い説明:

コードの各スニペットについて、同等のpythonと、より詳細な説明と推論を示します。

Jvw => J=eval(input())

Pythで入力を取得する標準的な方法。

Kr2 4=> K=range(2,4)=>K=[2,3]

最初の奇妙な部分は次のとおりです。エンドポイントを個別の変数として保存する代わりに、リストの要素として保存します。その理由はすぐに明らかになります。また、Pythではのような単純な割り当てを行う代わりにK[2 3)、範囲を使用してキャラクターを保存しています。

W-ZJ=> while Z-J=>while Z!=J

この時点で、「Zとは何ですか?定義していません」と尋ねることができます。Pythでは、すべての変数が事前定義されています。Zはたまたま0から始まります。ただし、Zは後で製品の値に設定されるため、このチェックはリストが正しい値になったらwhileループを終了するのに役立ちます。

~@K>JZ1 => K[J>Z] += 1

個別の変数ではなく、リストに値を保存する理由は次のとおりです。製品が現在高すぎるか低すぎるかに応じて、2つのエンドポイントのいずれかを増分します。エンドポイントが個別の変数である場合、それはかなり長い条件になりますが、リストのインデックス付けの魔法により、短くなります。また、このチェックが製品の前に来るという事実、およびZが0に初期化されるという事実[2,4]により、適切なエンドポイントである製品を最初に取得するまでにKが確実に確保されます。

=YurGHK=> Y=reduce(lambda G,H: range(G,H),K)=>Y=range(K[0],K[1])

ここで、製品が引き継がれる実際のリストが必要であり、成功すると印刷されます。明らかに、範囲関数を使用します。トリッキーなのは、範囲関数への入力を取得することにあります。リストにインデックスを付けることでこれを行う明白な方法は次のようになります=Yr'K@K1。ただし、この2つの要素のリストでreduce関数を使用することで、文字ごとに短縮できます。

=Zu*NTY => Z=reduce(lambda N,T: N*T,Y)

そして今、この問題のすべてのポイントについて、リストの積を見つけるためのリデュース操作。

) =>終了中

Y => print(Y)

成功したら、リストを印刷します。

実行例:

$ cat seq_prod 
JvwKr2 4W-ZJ~@K>JZ1=YurGHK=Zu*NTY)Y

$ cat seq_prod | python3 pyth.py
<debug stuff>
==================================================
[9, 10, 11, 12, 13, 14, 15, 16]

1

Java-115

void f(int i){for(int j=2;j<i;j++)for(int k=1,x=j;(x*=j+k)<i;k++);if(x==i)for(i=j;i<j+k;i++)System.out.println(i);}

ゴルフがやや少ない:

void f(int i) {
 for(int j=2; j<i; j++)
  for(int k=1, x=j; (x*=j+k) < i; k++);
   if(x == i)
    for(i=j; i<j+k; i++)
     System.out.println(i);
}

ええ、関数を作成して戻り値を出力しました。ここで以前にそれを見たことはありません。
seequ 14

何も印刷することはできません...しかし、もしそれがいくらか出力を与えるなら、あなたはゴルフをSystem.out.printlnすることができます、System.out.printそして最後のセミコロンfor(int k=1,x=j;(x*=j+k)<i;k++)は不必要であるだけでなく、エラーを引き起こします。
Qwix 14

これは私にはうまくいきません。xjk最後に範囲外であるif/forためのブロック;。を削除すると;、何も印刷されません。
ジオビット14

1
@Qwixに変更するprintと、数字が一緒に実行されないように空白文字を追加する必要があります。
ジオビット14

1
@Geobits良い点!もしそれが私にいくらかの出力を与えていたら、おそらくそれを見たでしょう。
Qwix 14

1

Matlab(88)

コードは、数値がに格納されx、出力されることを想定していlます。

for n=2:12
r=ceil(x^(1/n))
for s=-3*n:n
l=r-s+(1:n)
if prod(l)==x
return 
end;end;l=x;end

13! > 2^32このコードは、長さが2から12までの製品のみを検索するため、このコードの実行時間は約0.001秒です。


1

スカラ-86

def p(n:Int)=(2 to n).flatMap(i=>(i to n).map(i to _-1).find(_.product==n)).headOption

このコードは非常に効率的ではありませんが、最適化するとさらに数文字しか追加されません。機能的なアプローチを使用して、可能なすべての連続シーケンスの積を確認します。(整数の連続したシーケンスは、ScalaではRangeオブジェクトとして表されます)

なし:

def product(n: Int): Option[Range] = {
  def productStartingAt(start: Int): Option[Range] =
    (start to n-1).map(start to _).find(_.product == n)

  (2 to n).flatMap(i => productStartingAt(i)).headOption
}

1

CJam は現在、計算時間が長いため、大きな数値では機能しません。

これは私の最短のCJamコードです。http://cjam.aditsu.net/でテストします。入力方法をAとして定義します。0からA-1までのすべての数値の配列を作成します。0を蹴る; 配列内のすべての数値を乗算するまで最小の数値をキックすることは、A以下です。Aより大きいかどうかを確認します。そうでない場合は、0〜A-2の配列を作成します。そして答えが見つかるまで繰り返します。何も見つからない場合、例外がスローされます。数字の間にスペースが必要だとは考えていなかったので、数字は32文字の2番目のコードに含まれています。

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g" "*

あなたの答えは遅すぎて有効ではないと思います。有効な32ビット整数で5分以内に完了する必要があることに注意してください。3600060000 == 60000 * 60001にかかる時間は?
isaacg 14

公正な点、私はそれを作り直し、短い場合投稿します
ケイン14

再作業する場合は、それまでこの回答を削除するか、何らかの理由で現在無効であることを示してください。
isaacg 14

1

ダーツ-102文字

これは遅い実装です。より速くすることができますが、それはより多くの文字を必要とします(までループするだけのようにi*i<n

f(n,[i=2]){
  t(j,p,a)=>p<n?t(++j,p*j,a..add(j)):p>n?f(n,i+1):a;
  for(;i<n;i++)if(n%i<1)return t(i,i,[i]);
}

(102文字には、改行や先行スペースはありません)。

それを使用するには、次のようにします。

main() {
  print(f(123456789*123456790));
}

0

Javascript、88

ゴルフコード:

function f(a){for(i=2;i<a;i++){b=[1];for(j=i;j>1;j--)if((b[0]*=b[i-j+1]=j)==a)alert(b)}}

読みやすい(適切な間隔の)コード:

function f(a){
    for(i=2;i<a;i++){
        b=[1];
        for(j=i;j>1;j--)
            if((b[0]*=b[i-j+1]=j)==a)
                alert(b);
    }
}

2から入力番号までの各番号について、現在の番号から2に戻る連続した整数の積を検索します。この積が入力数と等しい場合、一連の連続した数が元の入力数とともに出力されます。 。

入力番号と、その積が入力番号である連続した整数が出力されます。

たとえば、f(120)はテキスト「120,5,4,3,2」のアラートを生成し、次にテキスト「120,6,5,4」の2番目のアラートを生成します。

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