Hitung semua kotak hingga x hanya menggunakan penjumlahan dan pengurangan


11

Tujuannya adalah untuk menghitung semua kotak hingga xdengan penambahan dan pengurangan.

Aturan:

  1. Kode harus berupa fungsi yang mengambil jumlah kuadrat total untuk dihasilkan, dan mengembalikan array yang berisi semua kuadrat itu.
  2. Anda tidak dapat menggunakan fungsi string, struktur, perkalian, pembagian, atau built-in untuk menghitung kotak.
  3. Anda hanya dapat menggunakan array, bilangan bulat (bilangan bulat), penjumlahan, pengurangan. Tidak ada operator lain yang diizinkan!

Ini adalah pertanyaan , jadi kode terpendek dalam byte menang!


Ini pada dasarnya adalah algoritma yang paling dioptimalkan untuk penambahan kuadrat - atau, setidaknya, akan mendapatkan jawaban yang hampir sama.
Peter Taylor

2
@PeterTaylor Tidak, tidak sama, karena itu untuk algoritma yang paling optimal untuk penambahan kuadrat, tapi pertanyaan saya hanya meminta penambahan dan pengurangan.
Sikat gigi

Itu adalah hal yang sama. Sebagai saksi: jawaban saat ini untuk pertanyaan ini persis sama dengan sebagian besar jawaban untuk pertanyaan sebelumnya.
Peter Taylor

@ PeterTaylor saya mungkin bias, tapi saya benar-benar tidak berpikir itu sama sekali.
Sikat gigi

3
Pertanyaan ini mungkin sudah memiliki jawaban di tempat lain, tetapi itu tidak menjadikan pertanyaan itu duplikat dari pertanyaan lain.
Blacklight Shining

Jawaban:



6

C, 55 52 byte

int s(int n,int*r){for(int i=0,j=-1;n--;*r++=i+=j+=2);}

hanya menjumlahkan angka ganjil

  • n: jumlah kotak untuk dihitung
  • r: output array untuk menyimpan hasilnya
  • j: mengambil nilai berturut-turut 1, 3, 5, 7, ...
  • i: bertambah jsetiap iterasi

Edit

4 karakter dapat disimpan menggunakan deklarasi int implisit (> C99), tetapi ini berharga 1 char karena forinisialisasi tidak dapat berisi deklarasi di> C99. Kemudian kodenya menjadi

s(int n,int*r){int i=0,j=-1;for(;n--;*r++=i+=j+=2);}

Pemakaian

void main() {
    int r[20];
    s(20, r);
    for (int i = 0; i < 20 ; ++i) printf("%d\n", r[i]);
}  

Keluaran

1
4
9
16
25
36
49
(...)
361
400

1
logika itu Luar Biasa! Anda layak
diberi

5

GolfScript, 17 karakter

{[,{.+(1$+}*]}:F;

Penggunaan (lihat juga contoh online ):

10 F     # => [0 1 4 9 16 25 36 49 64 81]

Catatan: * adalah loop dan bukan operator perkalian.


BAIK; bagaimana cara kerjanya?
Sikat gigi

@toothbrush ,mengambil input dan mengubahnya ke array [0 1 ... n-1]. Kemudian *menyuntikkan blok kode yang diberikan ke array. Blok ini pertama kali menggandakan item saat ini ( .+) kurangi satu ( () dan kemudian tambahkan hasil sebelumnya 1$+(dengan kata lain, tambahkan 2j-1ke angka kuadrat sebelumnya). []melampirkan semuanya untuk mengembalikan array baru.
Howard

Bagus! Saya tidak tahu GolfScript, jadi saya bertanya-tanya bagaimana cara kerjanya.
Sikat gigi

5

Windows Batch, 115 byte

setlocal enabledelayedexpansion&for /l %%i in (1 1 %1)do (set a=&for /l %%j in (1 1 %%i)do set /a a+=%%i
echo.!a!)

Ini harus ditempatkan dalam file batch bukannya dijalankan dari cmd, dan ini menampilkan daftar ke konsol. Dibutuhkan jumlah kotak untuk dibuat dari argumen baris perintah pertama. Untuk sebagian besar menggunakan &bukan baris baru, namun satu masih diperlukan dan itu dihitung sebagai dua byte.

Perlu ekspansi variabel tertunda diaktifkan, ini bisa dilakukan dengan cmd /v:on. Dengan anggapan itu bukan, diperlukan ekstra setlocal enabledelayedexpansion&di awal (tanpa itu skrip adalah 83 byte).


4

Haskell - 30

f n=scanl1(\x y->x+y+y-1)[1..n]

Ini menggunakan fakta bahwa (n+1)^2=n^2+2n+1


4

Perl, 27 byte

sub{map{$a+=$_+$_-1}1..pop}

Matematika:

Matematika

Script untuk memanggil fungsi untuk mencetak 10 kotak:

#!/usr/bin/env perl
$square = sub{map{$a+=$_+$_-1}1..pop};
use Data::Dumper;
@result = &$square(10);
print Dumper \@result;

Hasil:

$VAR1 = [
          1,
          4,
          9,
          16,
          25,
          36,
          49,
          64,
          81,
          100
        ];

Suntingan:

  • Fungsi anonim (−2 byte, terima kasih skibrianski )
  • popbukannya shift(−2 byte, terima kasih skibiranski )

Saya tidak melihat alasan mengapa Anda perlu memberi nama sub Anda. TKI "sub {peta {$ a + = $ _ + $ _- 1} 1..shift}" tampaknya sah bagi saya, dan menghemat dua karakter.
skibrianski

@skibrianski: Fungsi anonim juga merupakan fungsi. Kelemahannya adalah pemanggilan fungsi sedikit lebih rumit.
Heiko Oberdiek

Benar, tapi itu ada di penelepon. Ada entri dalam bahasa lain yang mendefinisikan subs anonim, jadi saya pikir Anda aman =)
skibrianski

Dan Anda dapat menyimpan 2 karakter lainnya dengan menggunakan pop () alih-alih shift () karena hanya ada satu argumen.
skibrianski

@skibrianski: Benar, terima kasih.
Heiko Oberdiek

4

JavaScript - 32 Karakter

for(a=[k=i=0];i<x;)a[i]=k+=i+++i

Mengasumsikan xada variabel dan membuat array akuadrat untuk nilai 1..x.

ECMAScript 6 - 27 Karakter

b=[f=i=>b[i]=i&&i+--i+f(i)]

Memanggil f(x)akan mengisi array bdengan kotak untuk nilai 0..x.


Saya harus bertanya ... i+++ipada akhirnya ...?
WallyWest

2
k+=i+++isama dengan k += i + (++i)yang k+=i+i+1diikuti olehi=i+1
MT0

Oh itu jenius ... Aku harus menerapkannya pada codegolf berikutnya jika perlu! :)
WallyWest

Anda dapat menyimpan satu karakter dengan memindahkan deklarasi fungsi ke dalam array (mis b=[f=i=>b[i]=i&&i+--i+f(i)].).
Sikat gigi

Terima kasih - menyimpan satu karakter pada jawaban teratas juga dengan menggerakkan beberapa hal untuk menghapus titik koma.
MT0

4

Julia - 33

Setiap angka kuadrat dapat ditulis dengan penjumlahan dari angka ganjil:

julia> f(x,s=0)=[s+=i for i=1:2:(x+x-1)];f(5)
5-element Array{Int64,1}:
  1
  4
  9
 16
 25

Hai, dan selamat datang di CG.se! Bagus, jawaban singkat. Belum pernah mendengar tentang Julia, tetapi itu terlihat menarik.
Jonathan Van Matre

Bukankah "2x" perkalian di Julia? Anda bisa mengatakan x + x sebagai gantinya, yang akan dikenakan biaya hanya satu byte.
Glenn Randers-Pehrson

Anda benar (tidak memperhatikan), diedit.
CCP

Saya belum terbiasa dengan julia, tetapi mencarinya di manual online di docs.julialang.org/en/release-0.2 dan menemukan "Koefisien Numerik Literal: Untuk membuat formula numerik dan ekspresi umum lebih jelas, Julia mengizinkan variabel untuk segera didahului oleh numerik literal, menyiratkan perkalian. " Jadi ya, 2x adalah perkalian.
Glenn Randers-Pehrson

2

C ++ 99 81 78 80 78

int* f(int x){int a[x],i=1;a[0]=1;while(i<x)a[i++]=a[--i]+(++i)+i+1;return a;}  

percobaan pertama saya di kode-golf

Kode ini didasarkan pada
a = 2 xn - 1
di mana n adalah jumlah istilah dan sebuah adalah n th istilah dalam mengikuti seri
1, 3, 5, 9, 11, 13, .....
jumlah dari pertama 2 istilah = 2 kuadrat

jumlah dari 3 istilah pertama = 3 kuadrat
dan seterusnya ...


2
Saya pikir Anda dapat menghapus kawat gigi {}setelah forloop, karena hanya ada satu pernyataan. Ini dapat mengurangi jumlah char Anda dengan 2
user12205

1
Jika Anda mendeklarasikan array berukuran tidak konstan pada beberapa fungsi selain main () maka itu dapat diterima
Mukul Kumar

1
Kode ini memiliki perilaku yang tidak terdefinisi.
Kerrek SB

1
dan mengembalikan pointer ke data pada stack yang hancur selama pengembalian.
VX

1
@MukulKumar addition, subtraction, saya hanya menggunakan itu
mniip

2

Majelis DCPU-16 (90 byte)

Saya menulis ini dalam perakitan untuk prosesor fiksi, karena mengapa tidak?

:l
ADD I,1
SET B,0
SET J,0
:m
ADD J,1
ADD B,I
IFL J,I
SET PC,m
SET PUSH,B
IFL I,X
SET PC,l

Jumlahnya diharapkan berada di register X, dan register lain diharapkan menjadi 0. Hasil didorong ke stack, itu akan pecah begitu mencapai 65535 karena arsitektur 16 bit. Anda mungkin ingin menambahkan a SUB PC, 1ke ujung untuk mengujinya. Dikompilasi, program harus 20 byte (10 kata).


2

Haskell

f x=take x [iterate (+y) 0 !! y | y<- [0..]]

Ini pada dasarnya menciptakan perkalian, menggunakannya sendiri, dan memetakannya ke semua angka. f 10= [0,1,4,9,16,25,36,49,64,81]. Juga f 91= [0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,729,784,841,900,961,1024,1089,1156,1225,1296,1369,1444,1521,1600,1681,1764,1849,1936,2025,2116,2209,2304,2401,2500,2601,2704,2809,2916,3025,3136,3249,3364,3481,3600,3721,3844,3969,4096,4225,4356,4489,4624,4761,4900,5041,5184,5329,5476,5625,5776,5929,6084,6241,6400,6561,6724,6889,7056,7225,7396,7569,7744,7921,8100].


Bisakah Anda memperpanjang demo sedikit lebih besar dari 10?
Glenn Randers-Pehrson

2

Haskell, 34/23

n#m=m+n:(n+2)#(m+n)
f n=take n$1#0

atau, jika impor baik-baik saja:

f n=scanl1(+)[1,3..n+n]

Keluaran:

λ> f 8
[1,4,9,16,25,36,49,64]

1

Javascript 47

function f(n,a){return a[n]=n?f(n-1,a)+n+n-1:0}

r=[];f(12,r);console.log(r) pengembalian:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]


Bagus! Dalam EcmaScript 6: f=(n,a)=>a[n]=n?f(n-1,a)+n+n-1:0.
Sikat gigi

1
Saya benar-benar tidak sabar menunggu ECMAScript 6 untuk benar-benar memasuki penggunaan umum. Itu akan menjadi alasan sempurna untuk mempelajarinya.
Isiah Meadows

1
Bagian Fungsi Panah dari spesifikasi ECMAScript 6 telah ada di FireFox sejak versi 22.
MT0

1

Smalltalk, 52

f:=[:n||s|(s:=1)to:n collect:[:i|x:=s.s:=s+i+i+1.x]]

Mengembalikan array baru (yaitu tidak mengisi atau menambah yang sudah ada).

panggilan:

nilai f: 10

-> # (1 4 9 16 25 36 49 64 81 100)


1

python - 39

a=0
for i in range(5):a+=i+i+1;print(a)

Ganti 5dengan nilai apa pun. Ada saran?


1

Bash - 92 85 62 61 59 57

declare -i k=1;for((i=0;i++<$1;k+=i+i+1));do echo $k;done

Hasil:

$ ./squares.sh 10
1
4
9
16
25
36
49
64
81
100

Sunting: Saya mengganti loop dalam dengan algoritma dari solusi Haskell @ mniip.


1

Metode yang sama seperti di atas, di APL dan J:

APL: F←{+\1+V+V←¯1+⍳⍵}(17 karakter) berfungsi dengan sebagian besar varian APL (coba di sini )

dan bahkan lebih sedikit (hanya 14 karakter) dengan NGN APL: F←{+\1+V+V←⍳⍵}(lihat di sini )

J: f=:+/\@(>:@+:@:i.)(18 karakter)

sunting: solusi yang lebih baik dalam APL: F←{+\¯1+V+V←⍳⍵}(15 karakter)


1

C # (82)

int[] s(int n){int i,p=0;var r=new int[n];while(i<n){p+=i+i+1;r[i++]=p;}return r;}

1

C # - 93

int[]s(int l){int[]w=new int[l];while(l>=0){int i=0;while(i<l){w[l-1]+=l;i++;}l--;}return w;}

Ketika dipanggil dari metode lain dari kelas yang sama, akan mengembalikan array - [1,4,9,16,25,36...], hingga lelemen th.


Apakah Anda mencoba menghapus spasi di antara int[]dan sq? Saya tidak tahu C #, tetapi saya pikir itu harus berhasil.
user12205

Tidak, itu tidak akan berhasil. Int pertama [] adalah jenis pengembalian metode "sq". Saya dapat mengurangi nama metode menjadi hanya "s" :)
Rajesh

Maksud saya menggunakan int[]sqbukannya int[] sqdan int[]resbukannya int[] res. Ini membantu Anda menyimpan dua karakter, dan saya tidak mendapatkan kesalahan kompilasi dengan itu. Anda juga harus menggunakan pengidentifikasi karakter tunggal untuk sqdan resseperti yang Anda sarankan.
user12205

sepertinya ada yang salah dengan jawaban Anda
user12205

Indentasi kode dengan 4 spasi untuk meletakkannya di blok-kode dengan font monospace.
luser droog

1

Fortran II | IV | 66 | 77, 134 122 109 105

  SUBROUTINES(N,M)
  INTEGERM(N)
  K=0
  DO1I=1,N
  K=K+I+I-1
1 M(I)=K
  END

Sunting: hapus inner loop dan gunakan algoritma Haskell @ mniip sebagai gantinya.

Sunting: Diverifikasi bahwa subrutin dan driver valid Fortran II dan IV

Sopir:

  INTEGER M(100)
  READ(5,3)N
  IF(N)5,5,1
1 IF(N-100)2,2,5
2 CALLS(N,M)
  WRITE(6,4)(M(I),I=1,N)
3 FORMAT(I3)
4 FORMAT(10I6)
  STOP  
5 STOP1
  END

Hasil:

$ echo 20 | ./a.out
   1     4     9    16    25    36    49    64    81   100
 121   144   169   196   225   256   289   324   361   400

@miip, terima kasih, saya mengganti loop batin saya dengan kode Anda.
Glenn Randers-Pehrson

1

Python - 51

Di sini saya mendefinisikan fungsi seperti yang diminta oleh aturan.

Penggunaan sumangka ganjil:

f=lambda n:[sum(range(1,i+i+3,2))for i in range(n)]

Ini hanya menggunakan sum(builtin yang melakukan penambahan) dan range(builtin yang membuat array menggunakan penambahan). Jika Anda keberatan sum, kami dapat melakukan ini dengan reduce:

def g(n):v=[];reduce(lambda x,y:v.append(x) or x+y,range(1,i+i+3,2));return v

1

PHP, 92 byte

Ini perlu memiliki opsi "tag pendek" diaktifkan, tentu saja (untuk mengurangi 3 byte di awal).

<? $x=100;$a=1;$r=0;while($r<=$x){if($r){echo"$r ";}for($i=0,$r=0;$i<$a;$i++){$r+=$a;}$a++;}

Keluaran:

1 4 9 16 25 36 49 64 81 100 

1

Keempat - 48 byte

: f 1+ 0 do i 0 i 0 do over + loop . drop loop ;

Pemakaian:

7 f

Keluaran:

0 1 4 9 16 25 36 49
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.