Cannonball Conundrum

8

Tugas Anda adalah, dengan nomor input p, temukan jumlah pesanan meriam positif terkecil pyang BUKAN 1.

Definisi

Nomor bola meriam (of order p) adalah nomor yang keduanya:

  • An p-gonal number ( Lihat halaman ini ).
  • dan pnomor piramida -gonal.

    • The nth pjumlah piramida -gonal adalah jumlah dari 1 sampai nth pnomor -gonal.
      • (mis. 4th square pyramid number = 1 + 4 + 9 + 16 = 30)
    • Gambar di bawah ini mewakili nomor piramida kuadrat ke-4, sebagai piramida persegi. masukkan deskripsi gambar di sini

    • Untuk info lebih lanjut, kunjungi tautan ini .

Jumlah cannonball pesanan 3, misalnya, adalah 10, karena itu adalah:

  • Angka segitiga keempat ( 1 + 2 + 3 + 4 = 10)
  • dan nomor piramida segitiga ketiga. ( 1 + 3 + 6 = 10)

Formula

CATATAN: Jika Anda dapat menemukan (atau membuat) formula yang lebih berguna daripada yang saya miliki di sini, silakan posting di sini (atau kirim pesan kepada saya tentang hal obrolan pertanyaan).

  • Jika Anda tertarik, rumus untuk angka nke- p5 adalah:

masukkan deskripsi gambar di sini

  • Dan nth pjumlah -gonal piramida adalah:

masukkan deskripsi gambar di sini

Spesifikasi

  • p dijamin lebih besar dari 2.
  • Program harus memeriksa nilai untuk solusi phingga (dan termasuk) 2^16. Program Anda dapat melakukan apa saja jika tidak ada solusi yang ditemukan p.
  • Hanya indeks positif untuk n.

Uji kasus

  • 3output 10(bilangan segitiga ke-4, bilangan segitiga ke-3)
  • 4output 4900(angka kuadrat 70, angka piramid persegi 24)

Ini adalah kode-golf, jadi jawaban tersingkat dalam byte menang.

Catatan: Jika Anda memposting solusi, harap sertakan deskripsi tentang bagaimana kode bekerja.

Haruskah saya memulai hadiah untuk solusi yang lebih baik dan tidak menggunakan formula saya?

clismique
sumber
2
Bisakah Anda menambahkan lebih detail tentang apa nomor bola meriam itu? Tidak sepenuhnya jelas dari deskripsi Anda.
James
3
Apakah dijamin ada jawaban untuk itu n? Jika tidak, berapa kisaran nyang akan Anda gunakan?
Geobits
@DrGreenEggsandIronMan Diedit untuk membuat definisi. angka piramida -gonal ndan n-gonal tidak perlu didefinisikan.
clismique
@Gobobit Diedit untuk membuat rentang alih-alih menggunakan memori.
clismique
1
@DerpfacePython TL; DR: Angka meriam cukup langka. Cari sendiri.
R

Jawaban:

1

Python 3, 129 127 byte

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

Fungsi yang mengambil input melalui argumen dan mengembalikan output.

Ini adalah kekuatan kasar yang sangat naif, dan membutuhkan waktu yang sangat lama untuk ukuran sedang p; waktu eksekusi akan konyol untuk sesuatu yang mendekati maksimum diberikan untuk pdari 2^16, tetapi tidak ada alasan mengapa program ini tidak akan bekerja, diberikan waktu yang cukup.

Mungkin ada cara yang jauh lebih pendek dan lebih cepat untuk melakukan ini, tetapi saya pikir akan lebih baik untuk memposting sesuatu untuk memulai ini.

Bagaimana itu bekerja

Nilai pengembalian xdiinisialisasi ke 2, dan kemudian program hanya loop atas semua angka piramidal -gonal pdan p-gonal sesuai pesanan x. Jika angka piramidal -gonal pdan -gonal saat ini p, dihitung dengan menggunakan rumus, sama dengan satu sama lain dan untuk x, maka xharuslah angka bola meriam yang relevan dan ini dikembalikan. Lain, xbertambah, dan program mencoba lagi untuk nilai baru x.

Dalam hal bermain golf, produk Cartesian digunakan untuk menciutkan dua for-loop untuk bilangan piramidal gonal pdan p-gonal menjadi satu loop tunggal, dan rumus-rumus tersebut difaktorkan lebih lanjut untuk menghemat beberapa byte.

TheBikingViking
sumber
Ummm ... ini mungkin agak terlambat untuk mengatakan ... tapi ... formula saya salah. Anda hanya perlu mengubah rumus poligon.
clismique
@DerpfacePython Terima kasih telah menangkap itu.
TheBikingViking
1

JavaScript, 111 98 byte

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}

ungolfed

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
}

c tidak reinitialized dalam loop batin karena p berikutnya [b] pasti lebih besar dari g saat ini [c] (jadi kita harus pindah di anyway)

contoh

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>');
Titus
sumber
0

C, 107 byte

#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;}

Tidak digabungkan dengan parameter uji:

#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));
}

Ini menggunakan fakta bahwa bilangan p-gonal ke-n dapat didefinisikan sebagai n(1+(p-2)(n-1)/2)dan bilangan piramida adalah jumlah dari bilangan-bilangan di atas.

Saya pikir itu bisa golf lebih lanjut, mengingat itu tidak benar-benar perlu untuk variabel adiselamatkan.


sumber
Tunggu ... apakah idalam formula Anda angka imajiner i?
clismique
Ups, maaf. iseharusnya n. Saya memiliki berbagai notasi yang berserakan dalam penelitian saya. Saya tidak bisa membayangkan menggunakan nomor imajiner untuk masalah ini, dan saya pasti tidak bisa membayangkan menggunakannya dalam C.
0

program PHP lama, 115 106 byte

+16 untuk PHP saat ini, lihat di bawah

<?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;
  • loop selamanya
  • penggunaan: dengan PHP <4.2: dijalankan dari browser dengan <scriptpath>?n=<number>
    dengan PHP <5.4, tambahkan register_globals=1ke php.ini(+18?)
  • lihat jawaban JavaScript saya untuk deskripsi
  • +10 untuk PHP> = 5.4: ganti 1dengan $n=$_GET[n]. Atau ganti 1dengan $n=$argv[1], jalankan php -f <filename> <number>.
  • +6 untuk loop terbatas saat sukses: ganti echo$pdengandie(print$p)
  • +/- 0 untuk fungsi:

    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;}
    

    loop selamanya jika tidak menemukan apa pun. Ganti 1dengan $p<1e6untuk break at 100k atau dengan $p<$p+1untuk loop sampai integer overflow. (diuji dengan PHP 5.6)

contoh (berfungsi)

$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);

contoh keluaran

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
Titus
sumber