Calcola tutti i quadrati fino a x usando solo addizione e sottrazione


11

L'obiettivo è calcolare tutti i quadrati fino a xcon addizione e sottrazione.

Regole:

  1. Il codice deve essere una funzione che richiede il numero totale di quadrati da generare e restituisce un array contenente tutti quei quadrati.
  2. È possibile non utilizzare le stringhe, le strutture, moltiplicazione, divisione, o funzioni built-in per il calcolo piazze.
  3. È possibile utilizzare solo matrici, numeri interi (numeri interi), addizioni, sottrazioni. Non sono ammessi altri operatori!

Questa è una domanda di , quindi vince il codice più corto in byte!


Questo è essenzialmente l' algoritmo più ottimizzato per incrementare i quadrati - o, almeno, otterrà risposte praticamente identiche.
Peter Taylor,

2
@PeterTaylor No, non è lo stesso, in quanto è l'algoritmo più ottimizzato per l'incremento dei quadrati, ma la mia domanda richiede solo addizioni e sottrazioni.
Spazzolino da denti

Qual è la stessa cosa Come testimone: l'attuale risposta a questa domanda fa esattamente la stessa cosa della stragrande maggioranza delle risposte alla domanda precedente.
Peter Taylor,

@PeterTaylor Potrei essere di parte, ma non credo che sia affatto lo stesso.
Spazzolino da denti

3
Questa domanda potrebbe già avere risposte altrove, ma ciò non rende la domanda un duplicato dell'altra domanda.
Blacklight Shining

Risposte:



6

C, 55 52 byte

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

somma semplicemente i numeri dispari

  • n: numero di quadrati da calcolare
  • r: matrice di output per la memorizzazione dei risultati
  • j: prende i valori successivi 1, 3, 5, 7, ...
  • i: viene incrementato di jogni iterazione

modificare

4 caratteri possono essere salvati usando la dichiarazione int implicita (> C99), ma questo costa 1 carattere perché gli forinizializzatori non possono contenere una dichiarazione in> C99. Quindi il codice diventa

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

uso

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

Produzione

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

1
quella logica è eccellente! meriti +1
Mukul Kumar il

5

GolfScript, 17 caratteri

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

Utilizzo (vedi anche esempi online ):

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

Nota: * è un ciclo e non l'operatore di moltiplicazione.


OK; Come funziona?
Spazzolino da denti

@toothbrush ,accetta l'input e lo converte nell'array [0 1 ... n-1]. Quindi *immette il blocco di codice specificato nell'array. Questo blocco prima raddoppia l'elemento corrente ( .+) sottrae uno ( () e quindi aggiunge il risultato precedente 1$+(in altre parole, aggiungi 2j-1al numero quadrato precedente). []racchiude tutto per restituire un nuovo array.
Howard,

Grande! Non conosco GolfScript, quindi mi chiedevo come funzionasse.
Spazzolino da denti

5

Batch di Windows, 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!)

Questo dovrebbe essere inserito in un file batch anziché essere eseguito da cmd e restituisce l'elenco alla console. Ci vuole il numero di quadrati per creare dal primo argomento della riga di comando. Per la maggior parte utilizza &invece di newline, ne è comunque necessario uno e conta come due byte.

È necessario abilitare l'espansione variabile ritardata, questo può essere fatto con cmd /v:on. Supponendo che non lo sia, setlocal enabledelayedexpansion&era necessario un extra all'inizio (senza di esso lo script è di 83 byte).


4

Haskell - 30

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

Questo usa il fatto che (n+1)^2=n^2+2n+1


4

Perl, 27 byte

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

Matematica:

Matematica

Script per chiamare la funzione per stampare 10 quadrati:

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

Risultato:

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

modifiche:


Non vedo alcun motivo per cui è necessario nominare il tuo sub. IOW "sub {map {$ a + = $ _ + $ _- 1} 1..shift}" mi sembra legittimo e ti fa risparmiare due caratteri.
skibrianski

@skibrianski: anche una funzione anonima è una funzione. L'aspetto negativo è che la chiamata della funzione è un po 'più ingombrante.
Heiko Oberdiek,

Giusto, ma questo è il chiamante. Ci sono voci in altre lingue che definiscono sottotitoli anonimi, quindi penso che tu sia al sicuro =)
skibrianski

E puoi salvare altri 2 caratteri usando pop () invece di shift () poiché c'è solo un argomento.
skibrianski,

@skibrianski: giusto, grazie.
Heiko Oberdiek,

4

JavaScript - 32 caratteri

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

Presuppone l' xesistenza di una variabile e crea una matrice adi quadrati per i valori 1..x.

Caratteri ECMAScript 6 - 27

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

La chiamata f(x)popolerà l'array bcon i quadrati per i valori 0..x.


Devo chiedere ... i+++ialla fine ...?
WallyWest

2
k+=i+++iè la stessa k += i + (++i)che è la stessa k+=i+i+1seguita dai=i+1
MT0

Oh, questo è geniale ... Devo implementarlo nel mio prossimo codegolf se necessario! :)
WallyWest

È possibile salvare un carattere spostando la dichiarazione della funzione all'interno dell'array (ad es b=[f=i=>b[i]=i&&i+--i+f(i)].).
Spazzolino

Grazie - hai salvato anche un personaggio nella risposta in alto spostando le cose in tondo per rimuovere un punto e virgola.
MT0

4

Julia - 33

Qualsiasi numero quadrato può essere scritto da una somma di numeri dispari:

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

Ciao e benvenuto su CG.se! Risposta simpatica e concisa. Mai sentito parlare di Julia, ma sembra intrigante.
Jonathan Van Matre,

"2x" non è una moltiplicazione in Julia? Invece potresti dire x + x, che ti costerà solo un byte.
Glenn Randers-Pehrson,

Hai ragione (non l'ho notato), modificato.
PCC

Non conosco (ancora) julia, ma ho cercato nel manuale online su docs.julialang.org/en/release-0.2 e ho trovato "Coefficienti letterali numerici: per rendere più chiare le formule numeriche e le espressioni comuni, Julia consente le variabili essere immediatamente preceduto da un valore numerico letterale, che implica una moltiplicazione. " Quindi sì, 2x è una moltiplicazione.
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;}  

il mio primo tentativo nel code-golf

questo codice è basato su
un xn = 2 - 1
dove n è conteggio termine ed un è n esimo termine nella seguente serie
1, 3, 5, 9, 11, 13, .....
somma dei primi 2 termini = 2 squared

somma dei primi 3 termini = 3 quadrati
e così via ...


2
Penso che puoi rimuovere le parentesi graffe {}dopo il forciclo, poiché esiste solo un'istruzione. Questo può ridurre il conteggio dei caratteri di 2
user12205

1
Se dichiari matrici di dimensioni non costanti in una funzione diversa da main (), allora è accettabile
Mukul Kumar,

1
Questo codice ha un comportamento indefinito.
Kerrek SB,

1
e restituisce il puntatore ai dati sullo stack distrutti durante il ritorno.
VX,

1
@MukulKumar addition, subtraction, sto usando solo quelli
mniip

2

DCPU-16 Assembly (90 byte)

L'ho scritto in assemblea per un processore fittizio, perché perché no?

: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

Il numero dovrebbe essere nel registro X e altri registri dovrebbero essere 0. I risultati vengono spinti nello stack, si romperà quando raggiungerà 65535 a causa dell'architettura a 16 bit. Potresti voler aggiungere un SUB PC, 1alla fine per testarlo. Compilato, il programma dovrebbe essere di 20 byte (10 parole).


2

Haskell

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

Questo fondamentalmente inventa la moltiplicazione, la utilizza da sola e la mappa su tutti i numeri. f 10= [0,1,4,9,16,25,36,49,64,81]. Anche 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].


Puoi estendere la demo a un po 'più grande di 10?
Glenn Randers-Pehrson

2

Haskell, 34/23

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

oppure, se le importazioni vanno bene:

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

Produzione:

λ> 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) ritorna :
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144]


Grande! In EcmaScript 6: f=(n,a)=>a[n]=n?f(n-1,a)+n+n-1:0.
Spazzolino da denti

1
Non vedo davvero l'ora che ECMAScript 6 entri davvero nell'uso mainstream. Sarebbe la scusa perfetta per impararlo.
Isiah Meadows,

1
La parte Arrow Function della specifica ECMAScript 6 è stata in FireFox dalla versione 22.
MT0

1

Smalltalk, 52

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

Restituisce un nuovo array (ovvero non riempie o non si aggiunge a uno esistente).

chiamata:

valore f: 10

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


1

pitone - 39

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

Sostituisci 5con qualsiasi valore. Eventuali suggerimenti?


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

Risultato:

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

Modifica: ho sostituito il ciclo interno con l'algoritmo della soluzione Haskell di @ mniip.


1

Stesso metodo di cui sopra, in APL e J:

APL: F←{+\1+V+V←¯1+⍳⍵}(17 caratteri) funziona con la maggior parte delle varianti APL (provalo qui )

e anche meno (solo 14 caratteri) con NGN APL: F←{+\1+V+V←⍳⍵}(vedi qui )

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

modifica: soluzione migliore in APL: F←{+\¯1+V+V←⍳⍵}(15 caratteri)


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

Se chiamato da un altro metodo della stessa classe, restituirà l'array - [1,4,9,16,25,36...], fino lall'elemento th.


hai provato a rimuovere gli spazi tra int[]e sq? Non conosco C #, ma penso che dovrebbe funzionare.
user12205,

No, non funzionerà. Il primo int [] è il tipo restituito del metodo "sq". Posso ridurre il nome del metodo in modo che sia semplicemente "s" :)
Rajesh,

Intendo usare int[]sqinvece di int[] sqe int[]resinvece di int[] res. Questo ti aiuta a salvare due caratteri e non ho riscontrato alcun errore di compilazione. Inoltre, dovresti utilizzare identificatori a carattere singolo per sqe rescome hai suggerito.
user12205,

sembra che ci sia qualcosa di sbagliato nella tua risposta
user12205,

Indenta il codice con 4 spazi per inserirlo in un blocco di codice con carattere 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

Modifica: rimosso il ciclo interno e usato invece l'algoritmo Haskell di @ mniip.

Modifica: verificato che la subroutine e il driver siano validi Fortran II e IV

autista:

  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

Risultato:

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

@mniip, grazie, ho sostituito il mio ciclo interno con il tuo codice.
Glenn Randers-Pehrson,

1

Python - 51

Qui sto definendo una funzione come richiesto dalle regole.

Utilizzo sumdi numeri dispari:

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

Questo utilizza solo sum(un builtin che esegue l'aggiunta) e range(un builtin che crea array usando l'aggiunta). Se ti opponi sum, possiamo farlo con 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

Questo deve ovviamente avere l'opzione "short tag" abilitata (per radere 3 byte all'inizio).

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

Produzione:

1 4 9 16 25 36 49 64 81 100 

1

Avanti - 48 byte

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

Uso:

7 f

Produzione:

0 1 4 9 16 25 36 49
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.