Números quadrados triangulares


11

Os números quadrados são aqueles que assumem a forma de n^2onde n é um número inteiro. Estes também são chamados quadrados perfeitos, porque quando você pega a raiz quadrada deles, obtém um número inteiro.

Os 10 primeiros números quadrados são: ( OEIS )

0, 1, 4, 9, 16, 25, 36, 49, 64, 81


Números triangulares são números que podem formar um triângulo equilátero. O n-ésimo número do triângulo é igual à soma de todos os números naturais de 1 a n.

Os 10 primeiros números triangulares são: ( OEIS )

0, 1, 3, 6, 10, 15, 21, 28, 36, 45


Números triangulares quadrados são números quadrados e triangulares.

Os primeiros 10 números triangulares quadrados são: ( OEIS )

0, 1, 36, 1225, 41616, 1413721, 48024900, 1631432881, 55420693056, 1882672131025, 63955431761796


Há um número infinito de números quadrados, números triangulares e números triangulares quadrados.

Escreva um programa ou função nomeada que forneça um número de entrada (parâmetro ou stdin) n, calcule o nnúmero triangular quadrado th e o produz / retorna, onde n é um número diferente de zero positivo. (Para n = 1, retorne 0)

Para que o programa / função seja um envio válido, ele deve poder retornar pelo menos todos os números de triângulos quadrados menores que 2 ^ 31-1.

Bônus

-4 bytes por poder gerar todos os números triangulares quadrados menores que 2 ^ 63-1

-4 bytes por poder, teoricamente, produzir números triangulares quadrados de qualquer tamanho.

Penalidade de +8 bytes para soluções que levam tempo não polinomial.

Pilha de bônus.

Esse é o desafio do código-golfe, portanto, a resposta com o menor número de bytes vence.


Eu adicionei uma penalidade de 8 bytes para soluções que demoram> O (n) tempo para torná-lo mais justo para aqueles que desejam um código mais rápido.
Rodolphito

@Rodolvertice Eu não acho que você quer dizer tempo linear. A solução iterativa que tenho é o tempo quadrático, porque há netapas, e em cada etapa a aritmética leva tempo linear, porque o número de dígitos cresce linearmente n. Não acho que o tempo linear seja possível. A menos que você esteja dizendo que operações aritméticas são tempo constante?
xnor

1
@Rodolvertice Quero dizer que minha solução iterativa não é O (n). Eu acho que a coisa mais limpa a se fazer é dizer "tempo polinomial". Se você assume a aritmética linear do tempo, obtém coisas estranhas como uma solução usando a exponenciação chamada tempo constante. A amortização não entra em jogo aqui.
xnor

1
amor para ver algo assim marcado em mais rápido-code
Abr001am

2
"Os primeiros 10 números triangulares quadrados ..." Certamente você quis dizer 11? : P
Alex A.

Respostas:


8

CJam, 12 8 bytes

XUri{_34*@-Y+}*;

Faz uso da relação de recorrência do artigo da Wikipedia.

O código tem 16 bytes e se qualifica para os dois bônus.

Experimente on-line no intérprete CJam .

Como funciona

Meu código acabou sendo idêntico ao xnor em sempre em todos os aspectos, exceto pelo uso da pilha de CJam em vez de variáveis.

XU               e# Push 1 and 0 on the stack.
                 e# Since 34 * 0 - 1 + 2 = 1, this compensates for 1-based indexing.
  ri{        }*  e# Do int(input()) times:
     _34*        e#   Copy the topmost integer and multiply it by 34.
         @-      e#   Subtract the bottommost integer from the result.
           Y+    e#   Add 2.
               ; e# Discard the last result.

Ele roda instantaneamente para entradas muito grandes, mas mais de 3000 gera um erro de intervalo Javascript no intérprete online. Vou experimentá-lo na implementação de java.
Rodolphito

@Rodolvertice: mudei para uma abordagem iterativa. Na verdade, é mais curto e consome menos memória.
Dennis

8

Python 2, 45 - 4-4 = 37

a=1;b=0
exec"a,b=b,34*b-a+2;"*input()
print a

Repete usando a recorrência

f(0) = 1
f(1) = 0
f(k) = 34*f(k-1)-f(k-2)+2

Em teoria, isso suporta números de qualquer tamanho, mas é executado em tempo exponencial, portanto, não deve se qualificar para os bônus. Deve funcionar para números de qualquer tamanho. Por exemplo, para 100, dá

1185827220993342542557325920096705939276583904852110550753333094088280194260929920844987597980616456388639477930416411849864965254621398934978872054025

Uma solução recursiva usa 41 caracteres, mas não deve se qualificar porque leva tempo exponencial.

f=lambda k:k>2and 34*f(k-1)-f(k-2)+2or~-k

Isso é muito barato, um 'loop' pela multiplicação de strings, haha.
Rodolphito

@Rodolvertice: Na verdade, não é nada barato. Bastante inteligente e de fato bastante comum no site.
Alex A.

Acredito que sua solução recursiva se qualifica para o bônus nº 1, que o vincularia à execsolução. Se você puder alterar o limite de recursão, também poderá calcular um número de triângulo quadrado de qualquer tamanho, qualificando-o para o # 2. No entanto, não tenho certeza se isso se qualifica (@Rodolvertice).
Kade

7

Pitão, 16-4-4 = 8 bytes

Usa a fórmula recursiva do artigo OEIS.

K1uhh-*34G~KGtQZ

Ele usa o comando pós-atribuição, que é bastante novo e parece muito legal. Os usos reduzem aos n-1tempos de iteração devido à indexação baseada em 1.

K1            Set K=1
u       tQ    Reduce input()-1 times
         Z    With zero as base case
 hh            +2
  -           Subtract
   *34G       34 times iterating variable
   ~K         Assign to K and use old value
    G         Assign the iterating variable.

Parece ser polinomial, porque faz um loop n vezes e faz matemática e atribuição a cada iteração, mas eu não sou um cientista da computação. Termina n = 10000 quase instantaneamente.

Experimente aqui online .


Eu acho que você pode evitar subtrair 1 da entrada se você iniciar uma iteração novamente em 0,1 em vez de 1,0 - veja minha resposta do Python.
xnor

@xnor: Eu acho que ele já faz isso. No entanto, o resultado retornado pelo loop é seu b.
Dennis

5

Oásis , 7 - 4 - 4 = -1 (Não competindo)

34*c-»T

Experimente online!

Usos a(0) = 0, a(1) = 1; for n >= 2, a(n) = 34 * a(n-1) - a(n-2) + 2

O Oasis suporta números inteiros de precisão arbitrários, portanto deve poder subir para qualquer número, desde que não ocorra excesso de pilha. Deixe-me saber se isso não conta para o bônus devido ao estouro da pilha. Também é possível que esse algoritmo específico não seja polinomial e informe-me se for esse o caso.

Não competir porque o idioma pós-data é um desafio.

Explicação:

34*c-»T -> 34*c-»10

a(0) = 0
a(1) = 1
a(n) = 34*c-»

34*c-»
34*    # 34*a(n-1)
   c-  # 34*a(n-1)-a(n-2)
     » # 34*a(n-1)-a(n-2)+2

Solução alternativa:

-35*d+T

Em vez disso, usa a(n) = 35*(a(n-1)-a(n-2)) + a(n-3)


A pergunta diz For n=1 return 0, mas isso retorna 1. Isso é corrigível adicionando a opção -O .
Grimmy

4

JavaScript (ES6), 29-4 = 25 bytes

n=>n>1?34*f(n-1)-f(n-2)+2:n|0

Guardado 5 bytes graças a @IsmaelMiguel !

Eu tive que codificar o 0, 1 e os negativos para evitar recursões infinitas.

Console, eu nomeei a função f:

f(1);  // 0
f(13); // 73804512832419600
f(30); // 7.885505171090779e+42 or 7885505171090779000000000000000000000000000

EDIT : O JavaScript arredondará os números para 16 (15) dígitos (Spec) porque esses números são muito grandes, causando um estouro. Coloque 714341252076979033 No seu console JavaScript e veja por si mesmo. É mais uma limitação do JavaScript


Eu não acho que isso se qualifique para o bônus. f(15)deve retornar 85170343853180456676, não 85170343853180450000.
Dennis

@Dennis O JavaScript deve estar truncando-o. .-. Sim, o JavaScript é arredondado para 16 dígitos quando
Downgoat

Tente este: n=>n?n<2?0:34*f(n-1)-f(n-2)+2:1(31 bytes). Eu testei até o quinto número.
Ismael Miguel

1
Aqui você tem agora um 29-bytes solução a longo: n=>n>1?34*f(n-1)-f(n-2)+2:!!n. Ele retorna falseno 0, trueno 1e 36no 2. Se você quiser retornar um número, poderá substituí-lo !!npor +!!n.
Ismael Miguel

1
Corrigido o problema. Utilize este: n=>n>1?34*f(n-1)-f(n-2)+2:n|0(a mesma contagem de bytes, agora retorna sempre números)
Ismael Miguel

3

Excel VBA - 90 bytes

Usando a relação de recorrência da página da Wikipedia:

n = InputBox("n")
x = 0
y = 1
For i = 1 To n
Cells(i, 1) = x
r = 34 * y - x + 2
x = y
y = r
Next i

Quando executado, você é solicitado a n, a sequência até e incluindo n é emitida na coluna A:

resultado

Pode ser executado até e incluindo n = 202 antes de gerar um erro de estouro.


2

[Não está competindo] Pitão (14 - 4 - 4 = 6 bytes)

K1u/^tG2~KGQ36

Utilizou a primeira recorrência do OEIS , que após 0,1,36 você pode encontrar A n = (A n-1 -1) 2 / A n-2 . R Não competindo porque esta solução começa em 36, se você diminuir, divide por zero (a entrada 0 fornece 36). Também teve que codificar 36.

Experimente aqui


2

Java, 53 - 4 = 49 bytes

É outra recursão simples, mas muitas vezes não consigo postar Java com uma pontuação <50, então ...

long g(int n){return n<2?n<1?1:0:34*g(n-1)-g(n-2)+2;}

Agora, para algo não- recursivo, fica um pouco mais longo. Este é mais longo (112-4 = 108) e mais lento, por isso não sei por que o estou postando, exceto por ter algo iterativo:

long f(int n){long a=0,b,c,d=0;for(;a<1l<<32&n>0;)if((c=(int)Math.sqrt(b=(a*a+a++)/2))*c==b){d=b;n--;}return d;}

2

Julia, 51 bytes - 4 - 4 = 43

f(n)=(a=b=big(1);b-=1;for i=1:n a,b=b,34b-a+2end;a)

Isso usa a primeira relação de recorrência listada na página da Wikipedia para números triangulares quadrados. Ele calcula n = 1000 em 0,006 segundos, e n = 100,000 em 6,93 segundos. É alguns bytes mais longo que uma solução recursiva, mas é muito mais rápido.

Ungolfed + explicação:

function f(n)
    # Set a and b to be big integers
    a = big(1)
    b = big(0)

    # Iterate n times
    for i = 1:n
        # Use the recurrence relation, Luke
        a, b = b, 34*b - a + 2
    end

    # Return a
    a
end

Exemplos:

julia> for i = 1:4 println(f(i)) end
0
1
36
1225

julia> @time for i = 1:1000 println(f(i)) end
0
... (further printing omitted here)
elapsed time: 1.137734341 seconds (403573226 bytes allocated, 38.75% gc time)

2

PHP, 65 59 56-4 = 52 bytes

while($argv[1]--)while((0|$r=sqrt($s+=$f++))-$r);echo$s;

repita até que a raiz quadrada de $sseja ∈ℤ: adicione $fà soma $s, incremente $f;
repetir $argv[1]vezes.
soma de saída.


1

Prolog, 70 74 - 4-4 = 66

n(X,R):-n(X,0,1,R).
n(X,A,B,R):-X=0,R=A;Z is X-1,E is 34*B-A+2,n(Z,B,E,R).

n(100,R)Saídas em execução :

X = 40283218019606612026870715051828504163181534465162581625898684828251284020309760525686544840519804069618265491900426463694050293008018241080068813316496

Demora cerca de 1 segundo para executar n(10000,X)no meu computador.

Edit : A versão 66 é recursiva da cauda. A versão anterior não recursiva da cauda é a seguinte:

n(X,[Z|R]):-X>1,Y is X-1,n(Y,R),R=[A,B|_],Z is 34*A-B+2;X=1,Z=1,R=[0];Z=0.

Eles têm o mesmo comprimento em bytes, mas o não recursivo de cauda gera estouros de pilha além de um determinado ponto (no meu computador, por volta de 20500).


1

Javascript ES6, 77 75 71 caracteres

// 71 chars
f=n=>{for(q=t=w=0;n;++q)for(s=q*q;t<=s;t+=++w)s==t&&--n&console.log(s)}

// No multiplication, 75 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2)for(;t<=s;t+=++w)s==t&&--n&console.log(s)}

// Old, 77 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2){for(;t<s;t+=++w);s==t&&--n&console.log(s)}}
  • A solução é linear.
  • A solução pode gerar todos os números com menos de 2 ^ 53 devido ao tipo de número.
  • O próprio algoritmo pode ser usado para números ilimitados.

Teste:

f(11)

0
1
36
1225
41616
1413721
48024900
1631432881
55420693056
1882672131025
63955431761796


1

Gelatina , 13 - 8 = 5 bytes

Isso se qualifica para os dois bônus.

×8‘,µÆ²Ạ
0Ç#Ṫ

Experimente online!

Feito ao lado de caird coinheringaahing no chat .

Explicação

× 8 ', µÆ²Ạ Link auxiliar.

× 8 ~ 8 vezes o número.
  '~ Incremento.
   , ~ Emparelhado com o número atual.
    µ ~ Inicia um novo link monádico (1-arg).
     Vetorizado "Is Square?".
       All ~ Tudo. Retorne 1 somente se ambos forem verdadeiros.



0Ç # Ṫ ~ Link principal.

0 # ~ A partir de 0, colete os primeiros N números inteiros com resultados verdadeiros, quando aplicados:
 Ç ~ O último link como uma mônada.
   Last ~ Último elemento. Saída implicitamente.



0

APL (NARS), 67 caracteres, 134 bytes

r←f w;c;i;m
c←0⋄i←¯1⋄r←⍬
→2×⍳0≠1∣√1+8×m←i×i+←1⋄r←r,m⋄→2×⍳w>c+←1

teste:

  f 10
0 1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 

f pesquisaria em sequência quadrática os elementos que também são números triangulares, portanto eles devem seguir a fórmula de verificação triangular nas APLs: 0 = 1∣√1 + 8 × m com o número m para verificar.

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.