Calcule todos os quadrados até x usando apenas adição e subtração


11

O objetivo é calcular todos os quadrados até xcom adição e subtração.

Regras:

  1. O código deve ser uma função que pega o número total de quadrados a serem gerados e retorna uma matriz contendo todos esses quadrados.
  2. Você não pode usar strings, estruturas, multiplicação, divisão ou funções internas para calcular quadrados.
  3. Você só pode usar matrizes, números inteiros (números inteiros), adição, subtração. Nenhum outro operador é permitido!

Esta é uma questão de , então o código mais curto em bytes vence!


Este é essencialmente o algoritmo mais otimizado para incrementar quadrados - ou, pelo menos, obterá respostas praticamente idênticas.
Peter Taylor

2
@ PeterTaylor Não, não é o mesmo, pois esse é o algoritmo mais otimizado para incrementar quadrados, mas minha pergunta pede apenas adição e subtração.
Escova de dentes

Qual é a mesma coisa. Como testemunha: a presente resposta a esta pergunta faz exatamente o mesmo que a grande maioria das respostas à pergunta anterior.
Peter Taylor

@ PeterTaylor Eu posso ser tendencioso, mas eu realmente não acho que é a mesma coisa.
Escova de dentes

3
Essa pergunta já pode ter respostas em outros lugares, mas isso não faz da pergunta uma duplicata da outra pergunta.
Blacklight Shining

Respostas:



6

C, 55 52 bytes

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

simplesmente soma números ímpares

  • n: número de quadrados a calcular
  • r: matriz de saída para armazenar os resultados
  • j: pega os valores sucessivos 1, 3, 5, 7, ...
  • i: é incrementado jem cada iteração

Editar

4 caracteres podem ser salvos usando a declaração int implícita (> C99), mas isso custa 1 caracter porque os forinicializadores não podem conter uma declaração em> C99. Então o código se torna

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

Resultado

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

1
essa lógica é excelente! você merece +1
Mukul Kumar

5

GolfScript, 17 caracteres

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

Uso (veja também exemplos on-line ):

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

Nota: * é um loop e não o operador de multiplicação.


ESTÁ BEM; como funciona?
Escova de dentes

@toothbrush ,pega a entrada e a converte na matriz [0 1 ... n-1]. Em seguida, *injeta o bloco de código fornecido na matriz. Este bloco primeiro dobra o item atual ( .+) subtrai um ( () e depois adiciona o resultado anterior 1$+(em outras palavras, adiciona 2j-1ao número quadrado anterior). []inclui tudo para retornar um novo array.
247 Howard Howard

Ótimo! Não conheço o GolfScript, então me perguntei como funcionava.
Escova de dentes

5

Lote do Windows, 115 bytes

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

Isso deve ser colocado em um arquivo em lotes, em vez de ser executado a partir do cmd, e envia a lista para o console. É necessário o número de quadrados a serem criados a partir do primeiro argumento da linha de comando. Para a maior parte usada em &vez de novas linhas, uma ainda é necessária e conta como dois bytes.

Ele precisa de expansão variável atrasada ativada, isso pode ser feito cmd /v:on. Supondo que não, um extra setlocal enabledelayedexpansion&foi necessário no início (sem ele, o script tem 83 bytes).


4

Haskell - 30

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

Isso usa o fato de que (n+1)^2=n^2+2n+1


4

Perl, 27 bytes

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

Matemática:

Matemática

Script para chamar a função para imprimir 10 quadrados:

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

Resultado:

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

Editar% s:


Não vejo razão para você precisar nomear seu sub. IOW "sub {map {$ a + = $ _ + $ _- 1} 1..shift}" parece legítimo para mim e economiza dois caracteres.
skibrianski

@skibrianski: Uma função anônima também é uma função. A desvantagem é que a chamada da função é um pouco mais complicada.
Heiko Oberdiek 21/03

Certo, mas isso é do interlocutor. Há entradas em outros idiomas que definem subs anônimos, então eu acho que você está = seguras)
skibrianski

E você pode salvar outros 2 caracteres usando pop () em vez de shift (), pois há apenas um argumento.
precisa saber é o seguinte

@skibrianski: Certo, obrigado.
precisa saber é o seguinte

4

JavaScript - 32 caracteres

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

Assume que uma variável xexiste e cria uma matriz ade quadrados para valores 1..x.

ECMAScript 6 - 27 Caracteres

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

A chamada f(x)preencherá a matriz bcom os quadrados para valores 0..x.


Eu tenho que perguntar ... i+++ino final ...?
Wally West

2
k+=i+++ié o mesmo k += i + (++i)que é o mesmo que k+=i+i+1seguido pori=i+1
MT0 03/03

Oh, isso é genial ... Eu tenho que implementar isso no meu próximo codegolf, se necessário! :)
WallyWest 03/03

Você pode salvar um caractere movendo a declaração da função para dentro da matriz (por exemplo b=[f=i=>b[i]=i&&i+--i+f(i)]).
Escova de dentes

Obrigado - também salvou um caractere na resposta superior movendo as coisas para remover um ponto e vírgula.
MT0

4

Julia - 33

Qualquer número quadrado pode ser escrito por uma soma de números ímpares:

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

Olá, e bem-vindo ao CG.se! Resposta agradável e sucinta. Nunca ouvi falar de Julia, mas parece intrigante.
Jonathan Van Matre

"2x" não é uma multiplicação em Julia? Você pode dizer x + x, o que custará apenas um byte.
Glenn Randers-Pehrson

Você está certo (não notou), editado.
CCP

Ainda não estou familiarizado com julia, mas procurei no manual on-line em docs.julialang.org/en/release-0.2 e encontrei "Coeficientes literais numéricos: para tornar mais claras as fórmulas e expressões numéricas comuns, Julia permite variáveis ser precedido imediatamente por um literal numérico, implicando multiplicação ". Então sim, 2x é uma multiplicação.
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;}  

minha primeira tentativa no code-golf

esse código é baseada em
um xn = 2 - 1
, onde n é contagem de termo e um é n ésimo termo na seguinte série
1, 3, 5, 9, 11, 13, .....
soma dos primeiros 2 termos = 2 quadrado

soma dos primeiros 3 termos = 3 ao quadrado
e assim por diante ...


2
Eu acho que você pode remover o aparelho {}depois do forloop, pois há apenas uma declaração. Isso pode reduzir sua contagem de caracteres em 2
user12205

1
Se você declarar matrizes de tamanho não constante em alguma outra função além main (), então é aceitável
Mukul Kumar

1
Este código tem um comportamento indefinido.
Kerrek SB

1
e retorna o ponteiro para os dados na pilha destruída durante o retorno.
VX

1
@MukulKumar addition, subtraction, eu só estou usando aqueles
mniip

2

Conjunto DCPU-16 (90 bytes)

Eu escrevi isso em montagem para um processador fictício, porque por que não?

: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

Espera-se que o número esteja no registrador X, e espera-se que outros registradores sejam 0. Os resultados são enviados para a pilha; ele será interrompido quando atingir 65535 devido à arquitetura de 16 bits. Você pode adicionar um SUB PC, 1no final para testá-lo. Compilado, o programa deve ter 20 bytes (10 palavras).


2

Haskell

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

Isso basicamente inventa a multiplicação, usa o próprio e o mapeia sobre todos os números. f 10= [0,1,4,9,16,25,36,49,64,81]. Também 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].


Você pode estender a demo para um pouco maior que 10?
Glenn Randers-Pehrson

2

Haskell, 34/23

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

ou, se as importações estiverem corretas:

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

Resultado:

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


Ótimo! Em EcmaScript 6: f=(n,a)=>a[n]=n?f(n-1,a)+n+n-1:0.
Escova de dentes

1
Mal posso esperar para que o ECMAScript 6 entre realmente no uso convencional. Essa seria a desculpa perfeita para aprender.
Isiah Meadows

1
A parte Arrow Function da especificação ECMAScript 6 está no FireFox desde a versão 22.
MT0

1

Smalltalk, 52

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

Retorna uma nova matriz (ou seja, não preenche ou adiciona a uma existente).

ligar:

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

Substitua 5por qualquer valor. Alguma sugestã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

Resultado:

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

Edit: Substituí o loop interno pelo algoritmo da solução Haskell da @ mniip.


1

O mesmo método acima, em APL e J:

APL: F←{+\1+V+V←¯1+⍳⍵}(17 caracteres) funciona com a maioria das variantes de APL (tente aqui )

e menos ainda (apenas 14 caracteres) com NGN APL: F←{+\1+V+V←⍳⍵}(veja aqui )

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

edit: melhor solução em APL: F←{+\¯1+V+V←⍳⍵}(15 caracteres)


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

Quando chamado de outro método da mesma classe, retornará a matriz - [1,4,9,16,25,36...], até o lelemento.


você tentou remover os espaços entre int[]e sq? Não sei c #, mas acho que deve funcionar.
user12205

Não, isso não vai funcionar. Primeiro int [] é o tipo de retorno do método "sq". Posso reduzir o nome do método para pode ser apenas "s" :)
Rajesh

Quero dizer, usando em int[]sqvez de int[] sqe em int[]resvez de int[] res. Isso ajuda a salvar dois caracteres, e não obtive nenhum erro de compilação. Além disso, você deve usar identificadores de caracteres únicos para sqe rescomo sugeriu.
user12205

Parece que há algo de errado com a sua resposta
user12205

Recue o código com 4 espaços para colocá-lo em um bloco de código com fonte monoespaçada.
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

Edit: removeu o loop interno e usou o algoritmo Haskell do @ mniip.

Edit: Verificado que a sub-rotina e o driver são Fortran II e IV válidos

Motorista:

  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

Resultado:

$ 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, obrigado, substituí meu loop interno pelo seu código.
Glenn Randers-Pehrson

1

Python - 51

Aqui estou definindo uma função conforme solicitado pelas regras.

Utilização sumde números ímpares:

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

Isso usa apenas sum(um builtin que executa adição) e range(um builtin que cria matrizes usando adição). Se você se opuser sum, podemos fazer isso com 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 bytes

É necessário ter a opção "tags curtas" ativada, é claro (para cortar 3 bytes no início).

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

Resultado:

1 4 9 16 25 36 49 64 81 100 

1

Quarto - 48 bytes

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

Uso:

7 f

Resultado:

0 1 4 9 16 25 36 49
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.