Descomponer un número en triángulos

15

Dado un número entero n , descomponerlo en una suma de números triangulares máximos (donde T m representa el número triangular número m , o la suma de los números enteros de 1 a m ) de la siguiente manera:

  • mientras n> 0 ,

    • encuentre el número triangular más grande posible T m tal que T m ≤ n .

    • agregue m a la representación de descomposición triangular de n .

    • restar T m de n .

Por ejemplo, una entrada de 44 produciría una salida de 8311 , porque:

  • 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36 <44, pero 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45> 44.

    • el primer dígito es 8 ; reste 36 de 44 para obtener 8 sobrantes.
  • 1 + 2 + 3 = 6 <8, pero 1 + 2 + 3 + 4 = 10> 8.

    • el segundo dígito es 3 ; reste 6 de 8 para obtener 2 sobrantes.
  • 1 <2, pero 1 + 2 = 3> 2.

    • los dígitos tercero y cuarto deben ser 1 y 1 .

Use los dígitos del 1 al 9 para representar los primeros 9 números triangulares, luego use las letras de la a a la z (pueden escribirse en mayúsculas o minúsculas) para representar el número triangular del 10 al 35. Nunca se le dará una entrada que requerirá el uso de un "dígito" más grande.

Los límites en la entrada son 1 ≤ n <666 , y siempre será un número entero.

Todas las entradas y salidas posibles , y algunos casos de prueba seleccionados (listados como entrada, luego salida):

1 1
2 11
3 2
4 21
5 211
6 3
100 d32
230 k5211
435 t
665 z731

No se requiere una salida de para una entrada de -1/12 . :)

Pomo de la puerta
fuente
¿Pero una entrada de necesita tener una salida de ∞?
user75200

Respuestas:

8

JavaScript (ES6), 52 bytes

f=(n,t=0)=>t<n?f(n-++t,t):t.toString(36)+(n?f(n):'')

¿Cómo?

En lugar de calcular explícitamente T i  = 1 + 2 + 3 + ... + i , comenzamos con t = 0 y restamos iterativamente t + 1 de n mientras t <n , incrementando t en cada iteración. Cuando la condición ya no se cumple, un total de T t se resta de n y la salida se actualiza en consecuencia. Repetimos el proceso hasta n = 0 .

A continuación se muestra un resumen de todas las operaciones para n = 100 .

 n  |  t | t < n | output
----+----+-------+--------
100 |  0 | yes   | ""
 99 |  1 | yes   | ""
 97 |  2 | yes   | ""
 94 |  3 | yes   | ""
 90 |  4 | yes   | ""
 85 |  5 | yes   | ""
 79 |  6 | yes   | ""
 72 |  7 | yes   | ""
 64 |  8 | yes   | ""
 55 |  9 | yes   | ""
 45 | 10 | yes   | ""
 34 | 11 | yes   | ""
 22 | 12 | yes   | ""
  9 | 13 | no    | "d"
----+----+-------+--------
  9 |  0 | yes   | "d"
  8 |  1 | yes   | "d"
  6 |  2 | yes   | "d"
  3 |  3 | no    | "d3"
----+----+-------+--------
  3 |  0 | yes   | "d3"
  2 |  1 | yes   | "d3"
  0 |  2 | no    | "d32"

Casos de prueba

Arnauld
fuente
5

Jalea , 18 17 bytes

Ḥ‘½+.Ḟ©ịØB2®cạµ¹¿

Este es un enlace monádico que se imprime en STDOUT. Su valor de retorno es 0 y debe ignorarse.

Pruébalo en línea!

Dennis
fuente
4

cc, 74 bytes

?sa[2k_1K/1 4/la2*+v+0k1/dlardd*+2/-sadd10<t9>ula0<s]ss[87+P]st[48+P]sulsx

Esto es horrible

?sa             stores the input
[2k             sets precision to 2 so dc doesn't truncate 1/4
_1K/1 4/la2*+v+ uses the quadratic formula to find k, the next value to print
0k1/d           truncates k to an integer
lardd*+2/-sa    subtracts kth triangular number from the input 
dd10<t9>u       determines whether to print k as a letter or a digit         
la0<s]ss        loops when a is greater than 0
[87+P]st        prints k as a letter
[48+P]su        prints k as a digit (not p, as that leaves a trailing newline)
lsx             starts the main loop
poi830
fuente
3

JavaScript (ES6), 61 57 bytes

Guardado 4 bytes gracias a @Arnauld

f=(n,p=q=0)=>n?p-~q>n?q.toString(36)+f(n-p):f(n,++q+p):''
ETHproductions
fuente
1
Teníaf=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld
@Arnauld Oh, wow, eso es mucho mejor. Deberías publicarlo tú mismo ...
ETHproductions
1
Bien. En su versión, ¿sería seguro hacerlo f=(n,p=q=0)y f(n,++q+p)?
Arnauld
@Arnauld ¡Sí, gracias!
ETHproductions
2

Java 7, 81 bytes

int i=0;String c(int n){return i<n?c(n-++i):Long.toString(i,36)+(n>(i=0)?c(n):"");}

Puerto de la sorprendente respuesta JavaScript (ES6) de @Arnauld .
Mi propio enfoque fue casi el doble de largo ...

Pruébalo aquí.

Explicación:

int i=0;                  // Temp integer `i` (on class level)
String c(int n){          // Method with integer parameter and String return-type
  return i<n?             //  If `i` is smaller than the input integer
    c(n-++i)              //   Return a recursive call with input minus `i+1` (and raise `i` by 1 in the process)
   :                      //  Else:
    Long.toString(i,36)+  //   Return `i` as Base-36 +
     (n>(i=0)?            //   (If the input integer is larger than 0 (and reset `i` to 0 in the process)
      c(n)                //    Recursive call with the input integer
     :                    //   Else:
      "");                //    an empty String)
}                         // End of method
Kevin Cruijssen
fuente
2

Retina , 115 108 38 34 bytes

.+
$*¶
(\G¶|¶\1)+
0$1
+T`_w¶`w_`.¶

[¡Pruébelo en línea!] (Incluye paquete de prueba) Utiliza letras mayúsculas. Editar: ahorró 70 74 bytes adaptando descaradamente la respuesta de @ MartinEnder a ¿Es este número triangular? Explicación: El número se convierte en unario, luego el número triangular más grande posible se empareja repetidamente hasta que se agota el número. Cada partido se convierte en la base 36.

Neil
fuente
1

PHP, 74 bytes

for(;$n=&$argn;$t.=$i>10?chr($i+86):$i-1)for($i=0;$n>=++$i;)$n-=$i;echo$t;

Versión en línea

Jörg Hülsermann
fuente
0

R, 87 bytes

Originalmente, traté de preestablecer los posibles números triangulares. Esto llevó a este código con 105 bytes:

pryr::f(n,{l=cumsum(1:35)
k=''
while(n){y=tail(which(l<=n),1)
n=n-l[y]
k=paste0(k,c(1:9,letters)[y])}
k})

Esto requirió más indexación, así que probé la metodología de @Arnauld para reducir los bytes a 87.

pryr::f(n,{k='';while(n){t=0;while(t<n){t=t+1;n=n-t};k=paste0(k,c(1:9,letters)[t])};k})

Ambos códigos hicieron uso de las letras preestablecidas, ya que no pude encontrar una forma corta de convertir a la base 36.

Shayne03
fuente