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!

Sikat gigi
sumber
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

APL - 10

{+\1++⍨⍳⍵}

Contoh penggunaan:

{+\1++⍨⍳⍵}10
1 4 9 16 25 36 49 64 81 100

ngn APL demo

mniip
sumber
Hemat tiga byte:+\1+⍳+⍳
Adám
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
Coaumdio
sumber
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.

Howard
sumber
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).

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

mniip
sumber
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 )
Heiko Oberdiek
sumber
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.

MT0
sumber
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
PKC
sumber
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 ...

Mukul Kumar
sumber
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).

mackthehobbit
sumber
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].

PyRulez
sumber
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]
Flonk
sumber
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]

Michael M.
sumber
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)

blabla999
sumber
1

python - 39

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

Ganti 5dengan nilai apa pun. Ada saran?

qwr
sumber
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.

Glenn Randers-Pehrson
sumber
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)

Thomas Baruchel
sumber
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;}
Rik
sumber
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.

Rajesh
sumber
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
Glenn Randers-Pehrson
sumber
@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
nneonneo
sumber
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 
soapergem
sumber
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
Michael
sumber