Números cuadrados triangulares

11

Los números cuadrados son aquellos que toman la forma de n^2donde n es un número entero. Estos también se llaman cuadrados perfectos, porque cuando tomas su raíz cuadrada obtienes un número entero.

Los primeros 10 números cuadrados son: ( OEIS )

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


Los números triangulares son números que pueden formar un triángulo equilátero. El enésimo número de triángulo es igual a la suma de todos los números naturales del 1 al n.

Los primeros 10 números triangulares son: ( OEIS )

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


Los números triangulares cuadrados son números que son cuadrados y triangulares.

Los primeros 10 números triangulares cuadrados son: ( OEIS )

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


Hay un número infinito de números cuadrados, números triangulares y números triangulares cuadrados.

Escriba un programa o función con nombre que, dado un número de entrada (parámetro o stdin) n, calcule el nnúmero triangular cuadrado y lo emite / devuelve, donde n es un número positivo distinto de cero. (Para n = 1 devuelve 0)

Para que el programa / función sea una presentación válida, debe poder devolver al menos todos los números de triángulos cuadrados menores de 2 ^ 31-1.

Prima

-4 bytes para poder generar todos los números triangulares cuadrados menores que 2 ^ 63-1

-4 bytes para poder generar teóricamente números triangulares cuadrados de cualquier tamaño.

Penalización de +8 bytes para soluciones que toman tiempo no polinómico.

Bonus stack.

Este es un desafío de código de golf, por lo que gana la respuesta con la menor cantidad de bytes.

rodolphito
fuente
He agregado una penalización de 8 bytes para las soluciones que toman> O (n) tiempo para que sea más justo para aquellos que buscan un código más rápido.
rodolphito
@Rodolvertice No creo que te refieras al tiempo lineal. La solución iterativa que tengo es el tiempo cuadrático porque hay npasos, y en cada paso la aritmética toma tiempo lineal porque el número de dígitos crece linealmente n. No creo que el tiempo lineal sea posible. A menos que esté diciendo que las operaciones aritméticas son de tiempo constante?
xnor
1
@Rodolvertice Quiero decir que mi solución iterativa no es O (n). Creo que lo más limpio es decir "tiempo polinómico" en su lugar. Si asume la aritmética del tiempo lineal, obtiene cosas extrañas como una solución usando exponenciación que se llama tiempo constante. La amortización no entra en juego aquí.
xnor
1
encanta ver algo así etiquetado en el código más rápido
Abr001am
2
"Los primeros 10 números triangulares cuadrados ..." ¿ Seguramente quisiste decir 11? : P
Alex A.

Respuestas:

8

CJam, 12 8 bytes

XUri{_34*@-Y+}*;

Hace uso de la relación de recurrencia del artículo de Wikipedia.

El código tiene 16 bytes de longitud y califica para ambos bonos.

Pruébelo en línea en el intérprete de CJam .

Cómo funciona

Mi código resultó ser idéntico al de xnor en todos los aspectos, excepto que uso la pila de CJam en lugar de variables.

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.
Dennis
fuente
Se ejecuta instantáneamente para entradas muy grandes, pero más de 3000 da un error de rango Javascript en el intérprete en línea. Voy a probarlo en la implementación de Java.
rodolphito
@ Rodvertice: he cambiado a un enfoque iterativo. En realidad es más corto y requiere menos memoria.
Dennis
8

Pitón 2, 45 - 4 - 4 = 37

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

Itera el uso de la recurencia

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

En teoría, esto admite números de cualquier tamaño, pero se ejecuta en tiempo exponencial, por lo que no debería calificar para los bonos. Debería funcionar para números de cualquier tamaño. Por ejemplo, para 100, da

1185827220993342542557325920096705939276583904852110550753333094088280194260929920844987597980616456388639477930416411849864965254621398934978872054025

Una solución recursiva usa 41 caracteres, pero no debería calificar porque lleva tiempo exponencial.

f=lambda k:k>2and 34*f(k-1)-f(k-2)+2or~-k
xnor
fuente
Eso es bastante engañoso, un 'bucle' por multiplicación de cuerdas, jaja.
rodolphito
@ Rodolvertice: Realmente no es engañoso. Más bien inteligente, y de hecho bastante común en el sitio.
Alex A.
Creo que su solución recursiva califica para la bonificación n. ° 1, que la vincularía con la execsolución. Si se le permite cambiar el límite de recursividad, también podría calcular un número de triángulo cuadrado de cualquier tamaño, calificándolo para el n. ° 2. Sin embargo, no estoy seguro de si eso califica (@Rodolvertice).
Kade
7

Pyth, 16-4-4 = 8 bytes

Utiliza la fórmula recursiva del artículo de OEIS.

K1uhh-*34G~KGtQZ

Utiliza el comando de asignación posterior que es bastante nuevo y parece realmente genial. Los usos se reducen a n-1tiempos de iteración debido a la indexación basada en 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 se repite n veces y hace cálculos matemáticos y asignaciones en cada iteración, pero no soy un informático. Termina n = 10000 casi al instante.

Pruébalo aquí en línea .

Maltysen
fuente
Creo que puede evitar restar 1 de la entrada si comienza una iteración de nuevo en 0,1 en lugar de 1,0; vea mi respuesta de Python.
xnor
@xnor: Creo que él ya hace eso. Sin embargo, el resultado devuelto por el bucle es su b.
Dennis
5

Oasis , 7 - 4 - 4 = -1 (No competidor)

34*c-»T

Pruébalo en línea!

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

Oasis admite enteros de precisión arbitrarios, por lo que debería poder subir a cualquier número siempre que no se produzca un desbordamiento de la pila. Avíseme si esto no cuenta para la bonificación debido al desbordamiento de la pila. También es posible que este algoritmo en particular no sea polinómico, y avíseme si ese es el caso.

No competir porque el lenguaje es posterior a las fechas de desafío.

Explicación:

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

Solución alternativa:

-35*d+T

En cambio usa a(n) = 35*(a(n-1)-a(n-2)) + a(n-3)

Zwei
fuente
La pregunta dice For n=1 return 0, pero esto devuelve 1. Esto se puede solucionar agregando la opción -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 gracias a @IsmaelMiguel !

He tenido que codificar el 0, 1 y los negativos para evitar una recursión infinita.

Consola, he nombrado la función f,:

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

EDITAR : Resulta que JavaScript redondeará los números a 16 (15) dígitos (Especificaciones) porque estos números son demasiado grandes y causan un desbordamiento. Ponga 714341252076979033 en su consola JavaScript y compruébelo usted mismo. Es más una limitación de JavaScript

Downgoat
fuente
No creo que esto califique para el bono. f(15)debería volver 85170343853180456676, no 85170343853180450000.
Dennis
@Dennis JavaScript debe estar truncándolo. .-. Sí, JavaScript se redondea a 16 dígitos cuando
Downgoat
Pruebe este: n=>n?n<2?0:34*f(n-1)-f(n-2)+2:1(31 bytes). Lo he probado hasta el quinto número.
Ismael Miguel
1
Aquí ahora tiene un 29-bytes solución a largo: n=>n>1?34*f(n-1)-f(n-2)+2:!!n. Devuelve falseen 0, truesobre 1y 36sobre 2. Si desea que devuelva un número, puede reemplazarlo !!npor +!!n.
Ismael Miguel
1
Solucionado el problema. Use esto: n=>n>1?34*f(n-1)-f(n-2)+2:n|0(mismo conteo de bytes, ahora devuelve siempre números)
Ismael Miguel
3

Excel VBA - 90 bytes

Usando la relación de recurrencia de la página de 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

Cuando se ejecuta, se le solicita n, luego la secuencia hasta e incluyendo n se envía a la columna A:

salida

Se puede ejecutar hasta e incluyendo n = 202 antes de dar un error de desbordamiento.

Wightboy
fuente
2

[No compitiendo] Pyth (14 - 4 - 4 = 6 bytes)

K1u/^tG2~KGQ36

Usó la primera recurrencia de OEIS , que después de 0,1,36 puede encontrar A n = (A n-1 -1) 2 / A n-2 . A No compite porque esta solución comienza en 36, si baja, divide entre cero (por lo tanto, la entrada de 0 da 36). También tuve que codificar 36.

Pruébalo aquí

cmxu
fuente
2

Java, 53 - 4 = 49 bytes

Es otra recursión simple, pero no suelo publicar Java con una puntuación <50, así que ...

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

Ahora, para algo no recursivo, se vuelve un poco más largo. Este es más largo (112-4 = 108) y más lento, por lo que no estoy seguro de por qué lo estoy publicando, excepto para tener 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;}
Geobits
fuente
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)

Utiliza la primera relación de recurrencia que figura en la página de Wikipedia para números triangulares cuadrados. Calcula n = 1000 en 0.006 segundos yn = 100000 en 6.93 segundos. Es unos pocos bytes más largos que una solución recursiva, pero es mucho más rápido.

Ungolfed + explicación:

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

Ejemplos:

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)
Alex A.
fuente
2

PHP, 65 59 56-4 = 52 bytes

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

repita hasta que la raíz cuadrada de $ssea ​​∈ℤ: sume $fa la suma $s, incremente $f;
repetir $argv[1]tiempos.
suma de salida.

Titus
fuente
1

Prólogo, 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)Salidas corrientes :

X = 40283218019606612026870715051828504163181534465162581625898684828251284020309760525686544840519804069618265491900426463694050293008018241080068813316496

Tarda aproximadamente 1 segundo en ejecutarse n(10000,X)en mi computadora.

Editar : La versión 66 es recursiva de cola. La versión anterior no recursiva de cola es la siguiente:

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.

Tienen la misma longitud en bytes, pero el no recursivo de cola genera desbordamientos de pila más allá de cierto punto (en mi computadora, alrededor de 20500).

Fatalizar
fuente
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)}}
  • La solución es lineal.
  • La solución puede generar todos los números menos de 2 ^ 53 debido al tipo de números.
  • El algoritmo en sí mismo puede usarse para números ilimitados.

Prueba:

f(11)

0
1
36
1225
41616
1413721
48024900
1631432881
55420693056
1882672131025
63955431761796
Qwertiy
fuente
1

C, 68 bytes

Este fue un desafío divertido con C

main(o,k){o==1?k=0:0;k<9e9&&k>=0&&main(34*o-k+2,o,printf("%d,",k));}

Míralo correr aquí: https://ideone.com/0ulGmM

Albert Renshaw
fuente
1

Gelatina , 13 - 8 = 5 bytes

Esto califica para ambos bonos.

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

Pruébalo en línea!

Hecho junto a caird coinheringaahing en el chat .

Explicación

× 8 ', µÆ²Ạ ~ Enlace auxiliar.

× 8 ~ 8 veces el número.
  '~ Incremento.
   , ~ Emparejado con el número actual.
    µ ~ Inicia un nuevo enlace monádico (1-arg).
     Ʋ ~ Vectorizado "¿Es cuadrado?".
       All ~ Todos. Devuelve 1 solo si ambos son verdaderos.



0Ç # Ṫ ~ Enlace principal.

0 # ~ A partir de 0, recopile los primeros N enteros con resultados verdaderos, cuando se aplique:
 Ç ~ El último enlace como mónada.
   Ṫ ~ Último elemento. Salida implícita.
Sr. Xcoder
fuente
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

prueba:

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

f buscaría en secuencia cuadrática los elementos que también son números triangulares, por lo que deben seguir la fórmula de verificación triangular en las APL: 0 = 1∣√1 + 8 × m con el número m para verificar.

RosLuP
fuente