Oblicz wszystkie kwadraty do x, używając tylko dodawania i odejmowania

11

Celem jest obliczenie wszystkich kwadratów xz dodawaniem i odejmowaniem.

Zasady:

  1. Kod musi być funkcją, która generuje całkowitą liczbę kwadratów i zwraca tablicę zawierającą wszystkie te kwadraty.
  2. Można nie używać łańcuchów, struktur, mnożenie, dzielenie, lub wbudowanych funkcji do obliczania kwadraty.
  3. Możesz używać tylko tablic, liczb całkowitych (liczb całkowitych), dodawania, odejmowania. Żaden inny operator nie jest dozwolony!

To jest pytanie do , więc wygrywa najkrótszy kod w bajtach!

Szczoteczka do zębów
źródło
Jest to zasadniczo najbardziej zoptymalizowany algorytm zwiększania kwadratów - a przynajmniej otrzyma prawie identyczne odpowiedzi.
Peter Taylor
2
@PeterTaylor Nie, to nie to samo, ponieważ dotyczy to najbardziej zoptymalizowanego algorytmu zwiększania kwadratów, ale moje pytanie dotyczy tylko dodawania i odejmowania.
Szczoteczka do zębów
Co jest tym samym. Na dowód: obecna odpowiedź na to pytanie jest dokładnie taka sama, jak zdecydowana większość odpowiedzi na poprzednie pytanie.
Peter Taylor
@PeterTaylor Mogę być stronniczy, ale tak naprawdę nie sądzę, żeby było tak samo.
Szczoteczka do zębów
3
To pytanie może już odpowiedzi gdzie indziej, ale nie sprawiają, że pytanie w duplikat innej kwestii.
Blacklight Shining

Odpowiedzi:

6

APL - 10

{+\1++⍨⍳⍵}

Przykładowe użycie:

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

ngn demo APL

mniip
źródło
Zaoszczędź trzy bajty:+\1+⍳+⍳
Adám
6

C, 55 52 bajtów

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

po prostu sumuje liczby nieparzyste

  • n: liczba kwadratów do obliczenia
  • r: tablica wyjściowa do przechowywania wyników
  • j: przyjmuje kolejne wartości 1, 3, 5, 7, ...
  • i: zwiększa się o jprzy każdej iteracji

Edytować

4 znaki można zapisać za pomocą niejawnej deklaracji int (> C99), ale kosztuje to 1 znak, ponieważ forinicjatory nie mogą zawierać deklaracji w> C99. Następnie kod staje się

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

Stosowanie

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

Wynik

1
4
9
16
25
36
49
(...)
361
400
Coaumdio
źródło
1
ta logika jest doskonała! zasługujesz na +1
Mukul Kumar
5

GolfScript, 17 znaków

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

Zastosowanie (patrz także przykłady online ):

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

Uwaga: * jest pętlą, a nie operatorem mnożenia.

Howard
źródło
DOBRZE; jak to działa?
Szczoteczka do zębów
@toothbrush ,pobiera dane wejściowe i konwertuje je na tablicę [0 1 ... n-1]. Następnie *wstrzykuje podany blok kodu do tablicy. Ten blok najpierw podwaja bieżący element ( .+), odejmuje jeden ( (), a następnie dodaje poprzedni wynik 1$+(innymi słowy, dodaje 2j-1do poprzedniego numeru kwadratu). []obejmuje wszystko, aby zwrócić nową tablicę.
Howard
Świetny! Nie znam GolfScript, więc zastanawiałem się, jak to działa.
Szczoteczka do zębów
5

Pakiet Windows, 115 bajtów

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!)

Powinno to zostać umieszczone w pliku wsadowym zamiast uruchamiać się z cmd i wyświetla listę w konsoli. Pobiera liczbę kwadratów do utworzenia z pierwszego argumentu wiersza poleceń. W przeważającej części używa &zamiast nowego wiersza, jednak jeden jest nadal potrzebny i liczy się jako dwa bajty.

Wymaga włączenia opóźnionego rozszerzania zmiennych, można to zrobić za pomocą cmd /v:on. Zakładając, że tak nie jest, setlocal enabledelayedexpansion&na początku potrzebna była dodatkowa (bez niego skrypt ma 83 bajty).

mackthehobbit
źródło
4

Haskell - 30

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

Wykorzystuje to fakt (n+1)^2=n^2+2n+1

mniip
źródło
4

Perl, 27 bajtów

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

Matematyka:

Matematyka

Skrypt wywoływania funkcji w celu wydrukowania 10 kwadratów:

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

Wynik:

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

Edycje:

Heiko Oberdiek
źródło
Nie widzę powodu, dla którego musisz nazwać swój okręt podwodny. IOW „sub {map {$ a + = $ _ + $ _- 1} 1..shift}” wydaje mi się uzasadnione i oszczędza dwa znaki.
skibrianski
@skibrianski: Funkcja anonimowa jest również funkcją. Minusem jest to, że wywołanie funkcji jest nieco bardziej kłopotliwe.
Heiko Oberdiek
Tak, ale to zależy od osoby dzwoniącej. Istnieją wpisy w innych językach, które definiują anonimowe napisy, więc myślę, że jesteś bezpieczny =)
skibrianski
I możesz zapisać kolejne 2 znaki używając pop () zamiast shift (), ponieważ jest tylko jeden argument.
skibrianski
@skibrianski: Racja, dzięki.
Heiko Oberdiek
4

JavaScript - 32 znaki

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

Zakłada, że ​​zmienna xistnieje i tworzy tablicę akwadratów dla wartości 1..x.

ECMAScript 6 - 27 znaków

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

Wywołanie f(x)zapełni tablicę bkwadratami wartości 0..x.

MT0
źródło
Muszę zapytać ... i+++ina końcu ...?
WallyWest,
2
k+=i+++ijest taki sam jak ten, k += i + (++i)który jest taki sam, jak k+=i+i+1po którym następujei=i+1
MT0
Och, to jest genialne ... Muszę to zaimplementować w moim następnym codegolfie, jeśli to konieczne! :)
WallyWest
Możesz zapisać jeden znak, przenosząc deklarację funkcji do wnętrza tablicy (np b=[f=i=>b[i]=i&&i+--i+f(i)].).
Szczoteczka do zębów
Dzięki - zapisałem także jedną postać z górnej odpowiedzi, przesuwając rzeczy w okrąg, aby usunąć średnik.
MT0
4

Julia - 33

Dowolną liczbę kwadratową można zapisać przez zsumowanie liczb nieparzystych:

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
KPCh
źródło
Cześć, witamy na CG.se! Ładna, zwięzła odpowiedź. Nigdy nie słyszałem o Julii, ale wygląda intrygująco.
Jonathan Van Matre
Czy „2x” nie jest mnożeniem u Julii? Zamiast tego możesz powiedzieć x + x, co będzie kosztować tylko jeden bajt.
Glenn Randers-Pehrson
Masz rację (nie zauważyłem), edytowane.
KPCh
Nie znam (jeszcze) Julii, ale przejrzałem ją w podręczniku online na docs.julialang.org/en/release-0.2 i znalazłem „Współczynniki literału liczbowego: aby jaśniejsze wspólne wzory liczbowe i wyrażenia były bardziej przejrzyste, Julia zezwala na zmienne bezpośrednio poprzedzone literałem liczbowym, co oznacza pomnożenie ”. Więc tak, 2x to mnożenie.
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;}  

moja pierwsza próba gry w golfa kodowego

Kod ten jest oparty na
a = 2 Xn - 1
, gdzie n jest liczba Term jest n p określenie w serii 1, 3, 5, 9, 11, 13, ..... suma pierwszych 2 względem = 2 do kwadratu

suma pierwszych 3 haseł = 3 do kwadratu
i tak dalej ...

Mukul Kumar
źródło
2
Myślę, że można usunąć nawiasy klamrowe {}po forpętli, ponieważ istnieje tylko jedna instrukcja. Może to zmniejszyć liczbę
znaków
1
Jeśli zadeklarujesz tablice o nie stałej wielkości w jakiejś funkcji innej niż main (), wówczas jest to do przyjęcia
Mukul Kumar
1
Ten kod ma niezdefiniowane zachowanie.
Kerrek SB
1
i zwraca wskaźnik do danych na stosie zniszczonych podczas zwrotu.
VX
1
@MukulKumar addition, subtraction, używam tylko tych
mniip
2

Zespół DCPU-16 (90 bajtów)

Napisałem to w asemblerze dla fikcyjnego procesora, bo dlaczego nie?

: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

Oczekuje się, że liczba będzie w rejestrze X, a inne rejestry będą wynosić 0. Wyniki są wypychane na stos, pęknie, gdy osiągnie 65535 z powodu architektury 16-bitowej. Możesz dodać SUB PC, 1do końca, aby go przetestować. Skompilowany program powinien mieć 20 bajtów (10 słów).

mackthehobbit
źródło
2

Haskell

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

To w zasadzie wymyśla mnożenie, używa samego siebie i odwzorowuje je na wszystkich liczbach. f 10= [0,1,4,9,16,25,36,49,64,81]. Również 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
źródło
Czy możesz rozszerzyć wersję demonstracyjną do nieco większej niż 10?
Glenn Randers-Pehrson
2

Haskell, 34/23

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

lub, jeśli import jest w porządku:

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

Wynik:

λ> f 8
[1,4,9,16,25,36,49,64]
Flonk
źródło
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) zwroty :
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]

Michael M.
źródło
Świetny! W ECMAScript 6: f=(n,a)=>a[n]=n?f(n-1,a)+n+n-1:0.
Szczoteczka do zębów
1
Naprawdę nie mogę się doczekać, aż ECMAScript 6 naprawdę wejdzie do głównego nurtu. To byłaby idealna wymówka, aby się tego nauczyć.
Isiah Meadows
1
Część funkcji strzałki specyfikacji ECMAScript 6 znajduje się w FireFox od wersji 22.
MT0
1

Smalltalk, 52

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

Zwraca nową tablicę (tzn. Nie wypełnia ani nie dodaje do istniejącej).

połączenie:

wartość f: 10

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

blabla999
źródło
1

python - 39

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

Zastąp 5dowolną wartością. Jakieś sugestie?

qwr
źródło
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

Wynik:

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

Edycja: zastąpiłem wewnętrzną pętlę algorytmem z rozwiązania Haskell @ mniip.

Glenn Randers-Pehrson
źródło
1

Ta sama metoda, jak powyżej, w APL i J:

APL: F←{+\1+V+V←¯1+⍳⍵}(17 znaków) działa z większością wariantów APL (spróbuj tutaj )

a nawet mniej (tylko 14 znaków) z NGN APL: F←{+\1+V+V←⍳⍵}(patrz tutaj )

J: f=:+/\@(>:@+:@:i.)(18 znaków)

edycja: lepsze rozwiązanie w APL: F←{+\¯1+V+V←⍳⍵}(15 znaków)

Thomas Baruchel
źródło
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
źródło
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;}

Wywołany z innej metody tej samej klasy, zwróci tablicę - [1,4,9,16,25,36...]aż do lelementu.

Rajesz
źródło
próbowałeś usunąć spacje między int[]i sq? Nie znam C #, ale myślę, że powinno działać.
user12205
Nie, to nie zadziała. Pierwsza int [] to zwracana metoda „sq”. Mogę zredukować nazwę metody do „s” :)
Rajesh
Mam na myśli używanie int[]sqzamiast int[] sqi int[]reszamiast int[] res. Pomaga to zaoszczędzić dwa znaki i nie wystąpiły przy tym żadne błędy kompilacji. Powinieneś także używać identyfikatorów jednoznakowych dla sqi resjak sugerowałeś.
user12205
wygląda na to, że coś jest nie tak z twoją odpowiedzią
użytkownik12205
Wcięcie kodu z 4 spacjami, aby umieścić go w bloku kodu z czcionką o stałej szerokości.
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

Edycja: usunięto wewnętrzną pętlę i zamiast niej użyto algorytmu Haskell @ mniip.

Edycja: Zweryfikowano, że podprogram i sterownik są ważne w Fortran II i IV

Kierowca:

  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

Wynik:

$ 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
źródło
@mniip, dzięki, zastąpiłem moją wewnętrzną pętlę twoim kodem.
Glenn Randers-Pehrson
1

Python - 51

Tutaj definiuję funkcję zgodnie z wymaganiami reguł.

Używanie sumliczb nieparzystych:

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

To używa tylko sum(wbudowane, które wykonuje dodawanie) i range(wbudowane, które tworzy tablice przy użyciu dodawania). Jeśli sprzeciwisz się sum, możemy to zrobić za pomocą reduce:

def g(n):v=[];reduce(lambda x,y:v.append(x) or x+y,range(1,i+i+3,2));return v
nneonneo
źródło
1

PHP, 92 bajty

To oczywiście musi mieć włączoną opcję „krótkich tagów” ​​(aby zgolić 3 bajty na początku).

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

Wynik:

1 4 9 16 25 36 49 64 81 100 
Soergergem
źródło
1

Dalej - 48 bajtów

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

Stosowanie:

7 f

Wynik:

0 1 4 9 16 25 36 49
Michael
źródło