Membusuk angka menjadi segitiga


15

Dengan bilangan bulat n , dekomposisikan menjadi jumlah bilangan segitiga maksimal (di mana T m mewakili bilangan segitiga ke- m , atau jumlah bilangan bulat dari 1 ke m ) sebagai berikut:

  • sementara n> 0 ,

    • menemukan kemungkinan terbesar nomor segitiga T m sehingga T m ≤ n .

    • tambahkan m pada representasi dekomposisi-segitiga dari n .

    • kurangi T m dari n .

Misalnya, input 44 akan menghasilkan output 8311 , karena:

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

    • digit pertama adalah 8 ; kurangi 36 dari 44 untuk mendapatkan 8 sisa.
  • 1 + 2 + 3 = 6 <8, tetapi 1 + 2 + 3 + 4 = 10> 8.

    • digit kedua adalah 3 ; kurangi 6 dari 8 untuk mendapatkan 2 sisa.
  • 1 <2, tetapi 1 + 2 = 3> 2.

    • digit ketiga dan keempat harus 1 dan 1 .

Gunakan angka 1 hingga 9 untuk mewakili 9 angka segitiga pertama, kemudian gunakan huruf a sampai z (dapat dikapitalisasi atau huruf kecil) untuk mewakili angka segitiga ke-10 hingga ke-35. Anda tidak akan pernah diberi input yang mengharuskan penggunaan "digit" yang lebih besar.

Batas pada input adalah 1 ≤ n <666 , dan itu akan selalu menjadi bilangan bulat.

Semua input dan output yang mungkin , dan beberapa kasus uji yang dipilih (terdaftar sebagai input, lalu output):

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

Output untuk input -1/12 tidak diperlukan. :)


Tetapi apakah input perlu memiliki output ∞?
user75200

Jawaban:


8

JavaScript (ES6), 52 byte

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

Bagaimana?

Daripada secara eksplisit menghitung T i  = 1 + 2 + 3 + ... + i , kita mulai dengan t = 0 dan secara iteratif mengurangi t + 1 dari n sementara t <n , menambah t pada setiap iterasi. Ketika kondisi ini tidak terpenuhi lagi, total T t telah dikurangi dari n dan output diperbarui sesuai. Kami ulangi prosesnya sampai n = 0 .

Di bawah ini adalah ringkasan dari semua operasi untuk 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"

Uji kasus


5

Jelly , 18 17 byte

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

Ini adalah tautan monadik yang mencetak ke STDOUT. Nilai pengembaliannya adalah 0 dan harus diabaikan.

Cobalah online!


4

dc, 74 byte

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

Ini mengerikan.

?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

3

JavaScript (ES6), 61 57 byte

Disimpan 4 byte berkat @Arnauld

f=(n,p=q=0)=>n?p-~q>n?q.toString(36)+f(n-p):f(n,++q+p):''

1
Saya punyaf=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld

@Arnauld Oh wow, itu jauh lebih baik. Anda harus mempostingnya sendiri ...
ETHproduksi

1
Baik. Dalam versi Anda, apakah itu aman untuk dilakukan f=(n,p=q=0)dan f(n,++q+p)?
Arnauld

@Arnauld Ya, terima kasih!
ETHproduksi

2

Java 7, 81 byte

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

Port dari jawaban JavaScript menakjubkan (ES6) @Arnauld .
Pendekatan saya sendiri hampir 2x lebih panjang ..

Coba di sini.

Penjelasan:

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

2

Retina , 115 108 38 34 byte

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

[Cobalah online!] (Termasuk test suite) Menggunakan huruf besar. Sunting: Disimpan 70 74 byte dengan tanpa malu-malu mengadaptasi jawaban @ MartinEnder untuk Apakah angka ini berbentuk segitiga? Penjelasan: Jumlahnya diubah menjadi unary, maka nomor segitiga yang paling mungkin dicocokkan berulang kali hingga jumlahnya habis. Setiap pertandingan kemudian dikonversi menjadi base 36.



0

R, 87 byte

Awalnya, saya mencoba mengatur angka Triangular yang mungkin. Ini menyebabkan kode ini dengan 105 byte:

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

Ini membutuhkan lebih banyak pengindeksan jadi saya mencoba metodologi dari @Arnauld untuk mengurangi byte ke 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})

Kedua kode memanfaatkan huruf yang telah ditetapkan, karena mereka saya tidak dapat menemukan cara singkat untuk mengkonversi ke basis 36.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.