Zerlege eine Zahl in Dreiecke

15

Zerlegen Sie eine ganze Zahl n in eine Summe maximaler Dreieckszahlen (wobei T m die m- te Dreieckszahl oder die Summe der ganzen Zahlen von 1 bis m darstellt ) wie folgt:

  • während n> 0 ist ,

    • finde die größtmögliche Dreieckszahl T m, so dass T m ≤ n ist .

    • hänge m an die Dreieckszerlegungsdarstellung von n an .

    • subtrahiere T m von n .

Zum Beispiel würde eine Eingabe von 44 eine Ausgabe von 8311 ergeben , weil:

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

    • die erste Ziffer ist 8 ; Subtrahiere 36 von 44, um 8 übrig zu haben.
  • 1 + 2 + 3 = 6 <8, aber 1 + 2 + 3 + 4 = 10> 8.

    • die zweite Ziffer ist 3 ; subtrahiere 6 von 8, um 2 übrig zu haben.
  • 1 <2, aber 1 + 2 = 3> 2.

    • Die dritte und vierte Ziffer müssen 1 und 1 sein .

Verwenden Sie die Ziffern 1 bis 9, um die ersten 9 Dreieckszahlen darzustellen, und verwenden Sie dann die Buchstaben a bis z (in Groß- oder Kleinbuchstaben), um die 10. bis 35. Dreieckszahl darzustellen. Sie werden niemals eine Eingabe erhalten, die die Verwendung einer größeren "Ziffer" erfordert.

Die Grenzen für die Eingabe sind 1 ≤ n <666 und es wird immer eine ganze Zahl sein.

Alle möglichen Ein- und Ausgaben sowie einige ausgewählte Testfälle (als Eingabe, dann Ausgabe aufgelistet):

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

Eine Ausgabe von für eine Eingabe von -1/12 ist nicht erforderlich. :)

Türknauf
quelle
Aber muss eine Eingabe von eine Ausgabe von ∞ haben?
User75200

Antworten:

8

JavaScript (ES6), 52 Byte

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

Wie?

Anstatt explizit T i  = 1 + 2 + 3 +… + i zu berechnen , beginnen wir mit t = 0 und subtrahieren iterativ t + 1 von n, während t <n ist , wobei wir t bei jeder Iteration inkrementieren . Wenn die Bedingung nicht mehr erfüllt ist, wurde insgesamt T t von n subtrahiert und die Ausgabe entsprechend aktualisiert. Wir wiederholen den Vorgang bis n = 0 ist .

Nachfolgend finden Sie eine Zusammenfassung aller Operationen für 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"

Testfälle

Arnauld
quelle
5

Jelly , 18 17 Bytes

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

Dies ist eine monadische Verknüpfung, die auf STDOUT gedruckt wird. Der Rückgabewert ist 0 und sollte ignoriert werden.

Probieren Sie es online!

Dennis
quelle
4

Gleichstrom, 74 Bytes

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

Das ist schrecklich.

?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
quelle
3

JavaScript (ES6), 61-57 Byte

4 Bytes dank @Arnauld eingespart

f=(n,p=q=0)=>n?p-~q>n?q.toString(36)+f(n-p):f(n,++q+p):''
ETHproductions
quelle
1
Ich hattef=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld
@Arnauld Oh wow, das ist viel besser. Sie sollten es selbst
posten
1
In Ordung. Wäre es in Ihrer Version sicher zu tun f=(n,p=q=0)und f(n,++q+p)?
Arnauld
@ Arnauld Ja, danke!
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):"");}

Port von @Arnauld 's erstaunlicher JavaScript (ES6) Antwort .
Mein eigener Ansatz war fast 2x so lang ..

Probieren Sie es hier aus.

Erläuterung:

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
quelle
2

Retina , 115 108 38 34 Bytes

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

[Online testen!] (Einschließlich Testsuite) Verwendet Großbuchstaben. Edit: 70 bis 74 Bytes durch schamloses Anpassen von @ MartinEnders Antwort auf Is this number triangular? Erläuterung: Die Zahl wird in eine unäre Zahl umgewandelt. Anschließend wird die größtmögliche dreieckige Zahl wiederholt abgeglichen, bis die Zahl erschöpft ist. Jede Übereinstimmung wird dann in die Basis 36 umgewandelt.

Neil
quelle
1

PHP, 74 Bytes

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

Online Version

Jörg Hülsermann
quelle
0

R 87 Bytes

Ursprünglich habe ich versucht, die möglichen Dreieckszahlen voreinzustellen. Dies führte zu diesem Code mit 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})

Dies erforderte mehr Indizierung, daher habe ich die Methode von @Arnauld ausprobiert, um die Bytes auf 87 zu reduzieren.

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

Beide Codes verwendeten die voreingestellten Buchstaben, da ich keinen kurzen Weg fand, sie in die Basis 36 zu konvertieren.

Shayne03
quelle