Décomposer un nombre en triangles

15

Étant donné un entier n , le décomposer en une somme de nombres triangulaires maximaux (où T m représente le m ème nombre triangulaire, ou la somme des entiers de 1 à m ) comme suit:

  • tandis que n> 0 ,

    • trouver le plus grand nombre triangulaire possible T m tel que T m ≤ n .

    • ajouter m à la représentation de décomposition triangulaire de n .

    • soustrayez T m de n .

Par exemple, une entrée de 44 donnerait une sortie de 8311 , car:

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

    • le premier chiffre est 8 ; soustrayez 36 de 44 pour obtenir 8 restants.
  • 1 + 2 + 3 = 6 <8, mais 1 + 2 + 3 + 4 = 10> 8.

    • le deuxième chiffre est 3 ; soustrayez 6 de 8 pour obtenir 2 restants.
  • 1 <2, mais 1 + 2 = 3> 2.

    • les troisième et quatrième chiffres doivent être 1 et 1 .

Utilisez les chiffres de 1 à 9 pour représenter les 9 premiers nombres triangulaires, puis utilisez les lettres de a à z (qui peuvent être en majuscules ou en minuscules) pour représenter le 10e au 35e nombre triangulaire. Vous ne recevrez jamais une entrée qui nécessitera l'utilisation d'un "chiffre" plus grand.

Les bornes sur l'entrée sont 1 ≤ n <666 , et ce sera toujours un entier.

Toutes les entrées et sorties possibles , et certains cas de test sélectionnés (répertoriés en entrée, puis en sortie):

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

Une sortie de pour une entrée de -1/12 n'est pas requise. :)

Poignée de porte
la source
Mais une entrée de doit-elle avoir une sortie de ∞?
user75200

Réponses:

8

JavaScript (ES6), 52 octets

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

Comment?

Plutôt que de calculer explicitement T i  = 1 + 2 + 3 +… + i , nous commençons par t = 0 et soustrayons itérativement t + 1 de n tandis que t <n , en incrémentant t à chaque itération. Lorsque la condition n'est plus remplie, un total de T t a été soustrait de n et la sortie est mise à jour en conséquence. Nous répétons le processus jusqu'à n = 0 .

Voici un résumé de toutes les opérations pour 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"

Cas de test

Arnauld
la source
5

Gelée , 18 17 octets

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

Il s'agit d'un lien monadique qui s'imprime sur STDOUT. Sa valeur de retour est 0 et doit être ignorée.

Essayez-le en ligne!

Dennis
la source
4

dc, 74 octets

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

C'est affreux.

?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
la source
3

JavaScript (ES6), 61 57 octets

4 octets enregistrés grâce à @Arnauld

f=(n,p=q=0)=>n?p-~q>n?q.toString(36)+f(n-p):f(n,++q+p):''
ETHproductions
la source
1
J'avaisf=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld
@Arnauld Oh wow, c'est bien mieux. Vous devriez le poster vous-même ...
ETHproductions
1
Bien. Dans votre version, serait-il sûr de faire f=(n,p=q=0)et f(n,++q+p)?
Arnauld
@Arnauld Oui, merci!
ETHproductions
2

Java 7, 81 octets

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

Port de @Arnauld « s JavaScript étonnant (ES6) réponse .
Ma propre approche était presque deux fois plus longue ..

Essayez-le ici.

Explication:

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
la source
2

Retina , 115 108 38 34 octets

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

[Essayez-le en ligne!] (Comprend la suite de tests) Utilise des lettres majuscules. Edit: sauvé 70 74 octets en adaptant sans vergogne la réponse de @ MartinEnder à Est-ce que ce nombre est triangulaire? Explication: Le nombre est converti en unaire, puis le plus grand nombre triangulaire possible est mis en correspondance de manière répétée jusqu'à épuisement du nombre. Chaque match est ensuite converti en base 36.

Neil
la source
1

PHP, 74 octets

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

Version en ligne

Jörg Hülsermann
la source
0

R, 87 octets

À l'origine, j'ai essayé de prérégler les nombres triangulaires possibles. Cela a conduit à ce code avec 105 octets:

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

Cela nécessitait plus d'indexation, j'ai donc essayé la méthodologie de @Arnauld pour réduire les octets à 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})

Les deux codes utilisaient les lettres prédéfinies, car je ne pouvais pas trouver un moyen rapide de convertir en base 36.

Shayne03
la source