Bilangan Kotak Segitiga

11

Angka kuadrat adalah angka yang berbentuk di n^2mana n adalah bilangan bulat. Ini juga disebut kuadrat sempurna, karena ketika Anda mengambil root kuadrat Anda mendapatkan bilangan bulat.

10 angka kuadrat pertama adalah: ( OEIS )

0, 1, 4, 9, 16, 25, 36, 49, 64, 81


Bilangan segitiga adalah angka yang dapat membentuk segitiga sama sisi. Angka segitiga ke-n sama dengan jumlah semua bilangan asli dari 1 ke n.

10 angka segitiga pertama adalah: ( OEIS )

0, 1, 3, 6, 10, 15, 21, 28, 36, 45


Angka segitiga kuadrat adalah angka yang berbentuk bujur sangkar dan segitiga.

10 angka segitiga persegi pertama adalah: ( OEIS )

0, 1, 36, 1225, 41616, 1413721, 48024900, 1631432881, 55420693056, 1882672131025, 63955431761796


Ada jumlah tak terbatas dari angka kuadrat, angka segitiga, dan angka segitiga kuadrat.

Tulis program atau fungsi bernama yang diberi nomor input (parameter atau stdin) n, hitung nangka segitiga kuadrat dan hasilkan / kembalikan, di mana n adalah bilangan nol bukan yang positif. (Untuk n = 1 mengembalikan 0)

Agar program / fungsi menjadi pengajuan yang valid, program harus dapat mengembalikan setidaknya semua angka segitiga persegi lebih kecil dari 2 ^ 31-1.

Bonus

-4 byte untuk dapat menampilkan semua angka segitiga kuadrat kurang dari 2 ^ 63-1

-4 byte karena secara teoritis dapat menghasilkan angka segitiga persegi dari berbagai ukuran.

+8 byte penalti untuk solusi yang membutuhkan waktu nonpolinomial.

Bonus menumpuk.

Ini adalah tantangan kode-golf, jadi jawaban dengan byte paling sedikit menang.

rodolphito
sumber
Saya telah menambahkan penalti 8 byte untuk solusi yang membutuhkan> O (n) waktu untuk membuatnya lebih adil bagi mereka yang menginginkan kode yang lebih cepat.
rodolphito
@ Radolvertice Saya tidak berpikir Anda maksud waktu linier. Solusi iteratif yang saya miliki adalah waktu kuadrat karena ada nlangkah - langkah, dan dalam setiap langkah aritmatika mengambil waktu linier karena jumlah digit tumbuh secara linear n. Saya tidak berpikir waktu linear itu mungkin. Kecuali Anda mengatakan operasi aritmatika adalah waktu yang konstan?
xnor
1
@ Radolvertice Maksud saya solusi iteratif saya bukan O (n). Saya pikir hal yang lebih bersih untuk dilakukan adalah mengatakan "waktu polinomial" sebagai gantinya. Jika Anda mengasumsikan aritmatika waktu linier, Anda mendapatkan hal-hal aneh seperti solusi menggunakan eksponensial yang disebut waktu konstan. Amortisasi tidak berlaku di sini.
xnor
1
senang melihat sesuatu seperti itu ditandai dalam kode tercepat
Abr001am
2
"10 angka segitiga persegi pertama ..." Tentunya maksudmu 11? : P
Alex A.

Jawaban:

8

CJam, 12 8 byte

XUri{_34*@-Y+}*;

Memanfaatkan hubungan perulangan dari artikel Wikipedia.

Kode panjangnya 16 byte dan memenuhi syarat untuk kedua bonus.

Cobalah online di penerjemah CJam .

Bagaimana itu bekerja

Kode saya ternyata identik dengan xnor di selalu setiap aspek, kecuali bahwa saya menggunakan tumpukan CJam, bukan variabel.

XU               e# Push 1 and 0 on the stack.
                 e# Since 34 * 0 - 1 + 2 = 1, this compensates for 1-based indexing.
  ri{        }*  e# Do int(input()) times:
     _34*        e#   Copy the topmost integer and multiply it by 34.
         @-      e#   Subtract the bottommost integer from the result.
           Y+    e#   Add 2.
               ; e# Discard the last result.
Dennis
sumber
Ini berjalan secara instan untuk input yang sangat besar, tetapi lebih dari 3000 memberikan kesalahan rentang Javascript pada penerjemah online. Saya akan mencobanya pada implementasi java.
rodolphito
@ Radolvertice: Saya telah beralih ke pendekatan berulang. Ini sebenarnya lebih pendek dan kurang memori intensif.
Dennis
8

Python 2, 45 - 4 - 4 = 37

a=1;b=0
exec"a,b=b,34*b-a+2;"*input()
print a

Iterasi menggunakan rekurensi

f(0) = 1
f(1) = 0
f(k) = 34*f(k-1)-f(k-2)+2

Secara teori, ini mendukung angka dari berbagai ukuran, tetapi berjalan dalam waktu eksponensial, sehingga tidak memenuhi syarat untuk bonus. Harus bekerja untuk nomor dari berbagai ukuran. Misalnya, untuk 100, memberi

1185827220993342542557325920096705939276583904852110550753333094088280194260929920844987597980616456388639477930416411849864965254621398934978872054025

Solusi rekursif menggunakan 41 karakter, tetapi seharusnya tidak memenuhi syarat karena membutuhkan waktu yang eksponensial.

f=lambda k:k>2and 34*f(k-1)-f(k-2)+2or~-k
Tidak
sumber
Itu cukup cheaty, 'loop' dengan perkalian string, haha.
rodolphito
@ Radolvertice: Tidak benar-benar curang sama sekali. Agak pintar, dan memang cukup umum di situs.
Alex A.
Saya percaya solusi rekursif Anda memenuhi syarat untuk bonus # 1, yang akan dikaitkan dengan execsolusi. Jika Anda diizinkan untuk mengubah batas rekursi, maka itu juga bisa menghitung angka segitiga persegi dari ukuran apa pun, memenuhi syarat untuk # 2. Namun, saya tidak yakin apakah itu memenuhi syarat (@Rodolvertice).
Kade
7

Pyth, 16 - 4 - 4 = 8 byte

Menggunakan rumus rekursif dari artikel OEIS.

K1uhh-*34G~KGtQZ

Ini menggunakan perintah post-assign yang cukup baru dan tampaknya sangat keren. Penggunaan mengurangi n-1waktu iterate karena pengindeksan berbasis 1.

K1            Set K=1
u       tQ    Reduce input()-1 times
         Z    With zero as base case
 hh            +2
  -           Subtract
   *34G       34 times iterating variable
   ~K         Assign to K and use old value
    G         Assign the iterating variable.

Tampaknya polinomial karena berulang kali dan melakukan matematika & tugas setiap iterasi, tapi aku bukan ilmuwan komputer. Selesai n = 10.000 hampir secara instan.

Coba di sini online .

Maltysen
sumber
Saya pikir Anda dapat menghindari mengurangi 1 dari input jika Anda memulai satu iterasi kembali pada 0,1 daripada 1,0 - lihat jawaban Python saya.
xnor
@ xnor: Saya pikir dia sudah melakukan itu. Namun, hasil yang dikembalikan oleh loop adalah milik Anda b.
Dennis
5

Oasis , 7 - 4 - 4 = -1 (Tidak bersaing)

34*c-»T

Cobalah online!

Penggunaan a(0) = 0, a(1) = 1; for n >= 2, a(n) = 34 * a(n-1) - a(n-2) + 2

Oasis mendukung bilangan bulat presisi yang sewenang-wenang, sehingga harus dapat naik ke nomor berapa pun selama tidak terjadi stack overflow. Beri tahu saya jika ini tidak termasuk bonus karena tumpukan tumpah. Mungkin juga bahwa algoritma khusus ini non-polinomial, dan beri tahu saya jika itu masalahnya.

Non-bersaing karena tantangan tanggal postingan bahasa.

Penjelasan:

34*c-»T -> 34*c-»10

a(0) = 0
a(1) = 1
a(n) = 34*c-»

34*c-»
34*    # 34*a(n-1)
   c-  # 34*a(n-1)-a(n-2)
     » # 34*a(n-1)-a(n-2)+2

Solusi alternatif:

-35*d+T

Alih-alih menggunakan a(n) = 35*(a(n-1)-a(n-2)) + a(n-3)

Zwei
sumber
Pertanyaannya mengatakan For n=1 return 0, tetapi ini mengembalikan 1. Ini dapat diperbaiki dengan menambahkan opsi -O .
Grimmy
4

JavaScript (ES6), 29-4 = 25 byte

n=>n>1?34*f(n-1)-f(n-2)+2:n|0

Disimpan 5 byte berkat @IsmaelMiguel !

Saya harus menuliskan kode 0, 1 dan negatif untuk menghindari rekursi tak terbatas.

Konsol, saya menamai fungsinya f,:

f(1);  // 0
f(13); // 73804512832419600
f(30); // 7.885505171090779e+42 or 7885505171090779000000000000000000000000000

EDIT : Ternyata JavaScript akan membulatkan angka menjadi 16 (15) digit (Spec) karena angka-angka ini terlalu besar yang menyebabkan overflow. Masukkan 714341252076979033 di konsol JavaScript Anda dan lihat sendiri. Ini lebih merupakan batasan JavaScript

Downgoat
sumber
Saya tidak berpikir ini memenuhi syarat untuk bonus. f(15)harus kembali 85170343853180456676, bukan 85170343853180450000.
Dennis
@Dennis JavaScript harus memotongnya. .-. Yup, JavaScript
membulatkan
Coba yang ini: n=>n?n<2?0:34*f(n-1)-f(n-2)+2:1(31 byte). Saya sudah menguji sampai nomor 5.
Ismael Miguel
1
Di sini Anda sekarang memiliki 29-byte solusi panjang: n=>n>1?34*f(n-1)-f(n-2)+2:!!n. Ia kembali falseaktif 0, trueterus 1dan 36terus 2. Jika Anda ingin mengembalikan nomor, Anda dapat menggantinya !!ndengan +!!n.
Ismael Miguel
1
Memperbaiki masalah. Gunakan ini: n=>n>1?34*f(n-1)-f(n-2)+2:n|0(jumlah byte yang sama, sekarang selalu kembali angka)
Ismael Miguel
3

Excel VBA - 90 byte

Menggunakan relasi perulangan dari halaman Wikipedia:

n = InputBox("n")
x = 0
y = 1
For i = 1 To n
Cells(i, 1) = x
r = 34 * y - x + 2
x = y
y = r
Next i

Ketika dieksekusi Anda diminta untuk n, maka urutan hingga dan termasuk n adalah output ke kolom A:

keluaran

Itu dapat dijalankan hingga dan termasuk n = 202 sebelum memberikan kesalahan overflow.

Wightboy
sumber
2

[Tidak Bersaing] Pyth (14 - 4 - 4 = 6 byte)

K1u/^tG2~KGQ36

Menggunakan pengulangan pertama dari OEIS , bahwa setelah 0,1,36 Anda dapat menemukan A n = (A n-1 -1) 2 / A n-2 . A Tidak bersaing karena solusi ini dimulai dari 36, jika Anda turun Anda membagi dengan nol (jadi input 0 memberi 36). Juga harus hardcode 36.

Coba di sini

cmxu
sumber
2

Java, 53 - 4 = 49 byte

Ini adalah rekursi sederhana yang lain, tetapi saya tidak sering memposting Jawa dengan skor <50, jadi ...

long g(int n){return n<2?n<1?1:0:34*g(n-1)-g(n-2)+2;}

Sekarang, untuk sesuatu yang non- rekursif, itu akan menjadi sedikit lebih lama. Yang ini lebih lama (112-4 = 108) -dan- lebih lambat, jadi saya tidak yakin mengapa saya mempostingnya kecuali memiliki sesuatu yang berulang:

long f(int n){long a=0,b,c,d=0;for(;a<1l<<32&n>0;)if((c=(int)Math.sqrt(b=(a*a+a++)/2))*c==b){d=b;n--;}return d;}
Geobit
sumber
2

Julia, 51 byte - 4 - 4 = 43

f(n)=(a=b=big(1);b-=1;for i=1:n a,b=b,34b-a+2end;a)

Ini menggunakan relasi perulangan pertama yang tercantum di halaman Wikipedia untuk angka segitiga persegi. Ini menghitung n = 1000 dalam 0,006 detik, dan n = 100000 dalam 6,93 detik. Ini beberapa byte lebih lama dari solusi rekursif tetapi jauh lebih cepat.

Penjelasan + tidak dikumpulkan:

function f(n)
    # Set a and b to be big integers
    a = big(1)
    b = big(0)

    # Iterate n times
    for i = 1:n
        # Use the recurrence relation, Luke
        a, b = b, 34*b - a + 2
    end

    # Return a
    a
end

Contoh:

julia> for i = 1:4 println(f(i)) end
0
1
36
1225

julia> @time for i = 1:1000 println(f(i)) end
0
... (further printing omitted here)
elapsed time: 1.137734341 seconds (403573226 bytes allocated, 38.75% gc time)
Alex A.
sumber
2

PHP, 65 59 56-4 = 52 byte

while($argv[1]--)while((0|$r=sqrt($s+=$f++))-$r);echo$s;

ulangi sampai akar kuadrat $sadalah ∈ℤ: tambahkan $fke jumlah $s, tambahkan $f;
ulangi $argv[1]kali.
jumlah keluaran.

Titus
sumber
1

Prolog, 70 74 - 4 - 4 = 66

n(X,R):-n(X,0,1,R).
n(X,A,B,R):-X=0,R=A;Z is X-1,E is 34*B-A+2,n(Z,B,E,R).

Menjalankan n(100,R)output:

X = 40283218019606612026870715051828504163181534465162581625898684828251284020309760525686544840519804069618265491900426463694050293008018241080068813316496

Butuh sekitar 1 detik untuk berjalan n(10000,X)di komputer saya.

Sunting : Versi 66 bersifat ekor-rekursif. Versi non-ekor-rekursif sebelumnya adalah sebagai berikut:

n(X,[Z|R]):-X>1,Y is X-1,n(Y,R),R=[A,B|_],Z is 34*A-B+2;X=1,Z=1,R=[0];Z=0.

Mereka memiliki panjang yang sama dalam byte tetapi non-tail-rekursif menghasilkan stack overflows melewati titik tertentu (di komputer saya, sekitar 20500).

Fatalisasi
sumber
1

Javascript ES6, 77 75 71 karakter

// 71 chars
f=n=>{for(q=t=w=0;n;++q)for(s=q*q;t<=s;t+=++w)s==t&&--n&console.log(s)}

// No multiplication, 75 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2)for(;t<=s;t+=++w)s==t&&--n&console.log(s)}

// Old, 77 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2){for(;t<s;t+=++w);s==t&&--n&console.log(s)}}
  • Solusinya linear.
  • Solusinya dapat menampilkan semua angka kurang dari 2 ^ 53 karena jenis angka.
  • Algoritme itu sendiri dapat digunakan untuk angka yang tidak terbatas.

Uji:

f(11)

0
1
36
1225
41616
1413721
48024900
1631432881
55420693056
1882672131025
63955431761796
Qwertiy
sumber
1

C, 68 byte

Ini adalah tantangan yang menyenangkan dengan C

main(o,k){o==1?k=0:0;k<9e9&&k>=0&&main(34*o-k+2,o,printf("%d,",k));}

Tonton di sini: https://ideone.com/0ulGmM

Albert Renshaw
sumber
1

Jelly , 13 - 8 = 5 byte

Ini memenuhi syarat untuk kedua bonus.

×8‘,µÆ²Ạ
0Ç#Ṫ

Cobalah online!

Dilakukan bersama caird coinheringaahing dalam obrolan .

Penjelasan

× 8 ', μƲẠ ~ Tautan bantuan.

× 8 ~ 8 kali jumlahnya.
  '~ Penambahan.
   , ~ Dipasangkan dengan nomor saat ini.
    μ ~ Memulai tautan monadik (1-arg) baru.
     Ʋ ~ Di-vektor-kan "Is Square?".
       Ạ ~ Semua. Kembalikan 1 hanya jika keduanya benar.



0Ç # Ṫ ~ Tautan utama.

0 # ~ Mulai dari 0, kumpulkan bilangan bulat N pertama dengan hasil yang benar, ketika diterapkan:
 Ç ~ Tautan terakhir sebagai monad.
   Ṫ ~ Elemen terakhir. Output secara implisit.
Tuan Xcoder
sumber
0

APL (NARS), 67 karakter, 134 byte

r←f w;c;i;m
c←0⋄i←¯1⋄r←⍬
→2×⍳0≠1∣√1+8×m←i×i+←1⋄r←r,m⋄→2×⍳w>c+←1

uji:

  f 10
0 1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 

f akan mencari dalam urutan kuadrat elemen-elemen yang merupakan nomor segitiga juga, sehingga mereka harus mengikuti rumus periksa segitiga dalam APLs: 0 = 1∣√1 + 8 × m dengan angka m untuk memeriksa.

RosLuP
sumber