キャノンボール難問


8

あなたの仕事は、入力番号を使用してp、p1ではない次数の最小の正の砲弾数を見つけることです。

定義

砲弾の数(次数p)は、次の両方の数です。

  • p-gonal数(このページを参照してください)。
  • とp正角ピラミッド番号。

    • n第p-gonalピラミッド数は、第一の和であるn第p-gonal番号。
      • (例4th square pyramid number = 1 + 4 + 9 + 16 = 30)
    • 次の図は、4番目の正方形のピラミッド番号を正方形のピラミッドとして表しています。 ここに画像の説明を入力してください

    • 詳細については、このリンクにアクセスしてください。

たとえば、次数3の砲弾数は10です。

  • 4番目の三角形の番号(1 + 2 + 3 + 4 = 10)
  • そして、第三の三角錐の数。(1 + 3 + 6 = 10)

フォーミュラ

注:ここにあるものよりも有用な式を見つけた(または作成した)場合は、ここに投稿してください(または、チャットでメッセージを送ってください)。

  • 興味があるなら、nth p-gonal数の式は次のとおりです。

ここに画像の説明を入力してください

  • そして、正多角形の数はn次のpとおりです。

ここに画像の説明を入力してください

スペック

  • p 2より大きいことが保証されています。
  • プログラムは、p最大(および最大)の解の値をチェックする必要があります2^16。の解決策が見つからない場合、プログラムは何かを行う可能性がありますp。
  • の正のインデックスのみn。

テストケース

  • 3出力10(4番目の三角形の番号、3番目の三角形のピラミッド番号)
  • 4出力4900(70番目の正方形の番号、24番目の正方形のピラミッド番号)

これはコードゴルフなので、バイト単位の最短の回答が優先されます。

注:ソリューションを投稿する場合は、コードの動作の説明を含めてください。

私は自分の公式を使用せず、より良い解決策のために賞金を始めるべきですか?


2
砲弾の番号が何であるかについてもう少し詳しく説明してもらえますか?説明から完全に明確ではありません。
— ジェームズ

3
いずれnかの答えがあることが保証されていますか?そうでない場合、どの範囲をn使用しますか?
— ジオビット2016

@DrGreenEg​​gsandIronMan編集して定義を行います。n-gonalおよびn-gonalピラミッド番号を定義する必要はありません。
— 5

@Geobitsメモリを使用する代わりに範囲を作成するために編集されました。
— 5

1
@DerpfacePython TL; DR:砲弾の数は非常にまれです。自分を探してください。
— Rɪᴋᴇʀ

回答:


1

Python 3、129 127バイト

def f(p):
 x=2
 while 1:
  for i in range(x*x):
   if i//x*((p-2)*i//x+4-p)/2==i%x*(i%x+1)*((p-2)*i%x+5-p)/6==x:return x
  x+=1

引数を介して入力を受け取り、出力を返す関数。

これは非常にナイーブなブルートフォースであり、適度な大きさであっても非常に長い時間がかかりpます。forの指定された最大値に近づくと、実行時間はばかげたものになりますpが2^16、十分な時間が与えられた場合、プログラムが機能しない理由はありません。

これを行う方法はおそらくもっと短くて速いでしょうが、これを始めるために何かを投稿するのは良いことだと思いました。

使い方

戻り値xはに初期化され2、プログラムは単にすべてのp-gonalおよびp-gonalピラミッド番号を順番にループしますx。現在場合p-gonalおよびp式を用いて計算-gonalピラミッド番号は、互いに及びに等しいx、次いでx関連砲弾の数でなければならず、これが返されます。そうでない場合xは、インクリメントされ、プログラムはの新しい値を再試行しますx。

ゴルフに関しては、デカルト積を使用してp-gonalおよびp-gonalピラミッド型の数値の2つのforループを単一のループに折りたたみ、式をさらに因数分解して数バイトを節約しました。


うーん...これは言うには遅すぎるかもしれません...しかし...私の式は間違っていました。多角形の式を変更するだけです。
— 5

@DerpfacePythonそれをキャッチしてくれてありがとう。
— TheBikingViking

1

JavaScript、111 98バイト

f=n=>{for(b=c=g=1;b++;)for(p=b*(b*3+b*b*(n-2)-n+5)/6;g<p;c++)if(p==(g=c*(c*n-c-c-n+4)/2))return p}

ない

f=n=>{
for(b=2,c=g=1;b<1e6;b++)    // run index b from 2 (to 100k)
    for(
        p=(b*b*3+b*b*b*(n-2)-b*(n-5))/6 // p=the b-th n-pyramidal number
        ;g<p&&c<1e6;c++)   // run while n-gonal is lower than n-pyramidal (and c below 100k)
        if(p==(
            g=(c*c*(n-2)-c*(n-4))/2     // g=the c-th n-gonal number
        )) return p                     // if they are equal, return
}

次のp [b]が現在のg [c]よりも確実に大きいため、cは内部ループで再初期化されません(とにかく移動する必要があります)

例

samples=[3,4,6,8,10,11,14,17,23,26,30,32,35,41,43,50,88]
for(i in samples) document.write('n='+(n=samples[i])+': '+f(n)+'<br>');

0

C、107バイト

#define X(x)(1+p/2.0*x)*++x
c(p,m,n,a,b){m=n=a=b=1;p-=2;do if(a>b)b+=X(n);else a=X(m);while(a^b);return a;}

テストパラメータを使用しない場合:

#include <stdio.h>

#define X(x)(1+p/2.0*x)*++x
int c(int p)
{
    int m = 1, n = 1, a = 1, b = 1;
    p -= 2;
    do
        if(b < X(m))
            b += X(n);
        else
            a = X(m);
    while(a != b);
    return a;
}

int main()
{
    printf("%d\n", c(3));
    printf("%d\n", c(4));
}

これは、n番目のpゴナル数が次のように定義されn(1+(p-2)(n-1)/2)、ピラミッド数が前述の数の合計であることを使用しています。

変数aを保存する必要は本当にないので、さらにゴルフをすることができると思います。


待って... iあなたの式の中で虚数iですか?
— クリスミック

おっと、ごめんなさい。iであることになっていますn。私の研究では、さまざまな表記が散らばっていました。私はこの問題のための架空の番号を使用して想像することはできません、と私は間違いなくCでそれを使用して想像することはできません

0

古いPHPプログラム、115 106バイト

+16現在のPHPについては、以下を参照してください

<?for($b=2;1;$b++)for($p=$b*($b*3+$b*$b*($n-2)-$n+5)/6;$g<$p;++$c)if($p==$g=$c*($c*$n-2*$c-$n+4)/2)echo$p;
  • 永遠にループする
  • 使用法:PHP <4.2の場合:ブラウザから<scriptpath>?n=<number>
    PHP <5.4で実行し、(+ 18?)に追加register_globals=1しphp.iniます
  • 説明については、JavaScriptの回答を参照してください
  • PHP> = 5.4のための10:置き換える1と$n=$_GET[n]。または、1と置き換えて$n=$argv[1]実行しphp -f <filename> <number>ます。
  • 成功した場合に有限のforループ6:置き換えるecho$pとdie(print$p)
  • 関数の+/- 0:

    function f($n){for($b=2;1;$b++)for($p=$b*($b*3+$b*$b*($n-2)-$n+5)/6;$g<$p;++$c)if($p==$g=$c*($c*$n-2*$c-$n+4)/2)return$p;}
    

    何も見つからない場合は、永久にループします。100kでブレークするために、または整数オーバーフローまでループするために1withで置き換えます。(PHP 5.6でテスト済み)$p<1e6$p<$p+1

例(関数について)

$samples=[3,4,6,8,10,11,14,17,23,26,30,32,35,41,43,50,88];
foreach($samples as $n)echo "<br>n=$n: ", f($n);

出力例

n=3: 10
n=4: 4900
n=6: 946
n=8: 1045
n=10: 175
n=11: 23725
n=14: 441
n=17: 975061
n=23: 10680265
n=26: 27453385
n=30: 23001
n=32: 132361021
n=35: 258815701
n=41: 55202400
n=43: 245905
n=50: 314755
n=88: 48280
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.