Bir sayıyı üçgenlere ayır


15

Bir tamsayıyı verilen N (maksimal üçgen sayıların toplamının içine ayrıştırılması, T m temsil ettiği m , üçgen numarası veya 1 ila tamsayılar toplamı inci m ) aşağıdaki gibi:

  • n> 0 iken ,

    • mümkün olan en büyük üçgen sayı bulmak T m öyle ki , T m ≤ n .

    • Ekleme m üçgen ayrıştırma gösterimine n .

    • çıkarma T m gelen n .

Örneğin, 44 girdisi 8311 çıktısı verir , çünkü:

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

    • ilk basamak 8'dir ; 8'i geride bırakmak için 36'dan 44'ü çıkartın .
  • 1 + 2 + 3 = 6 <8, ancak 1 + 2 + 3 + 4 = 10> 8.

    • ikinci basamak 3'tür ; almak için 8'den 6'ya çıkarma 2 arta kalan.
  • 1 <2, ancak 1 + 2 = 3> 2.

    • üçüncü ve dördüncü basamaklar 1 ve 1 olmalıdır .

İlk 9 üçgen sayıyı temsil etmek için 1'den 9'a kadar olan rakamları kullanın, daha sonra 10. ila 35. üçgen sayısını temsil etmek için a ila z arasındaki harfleri (büyük veya küçük olabilir) kullanın. Hiçbir zaman size daha büyük bir "basamak" kullanılmasını gerektirecek bir girdi verilmeyecektir.

Girişteki sınırlar 1 ≤ n <666'dır ve her zaman bir tamsayı olacaktır.

Tüm olası girişler ve çıkışlar ve seçilen bazı test senaryoları (giriş, ardından çıkış olarak listelenir):

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

-1/12 girişi için çıkışı gerekli değildir. :)


Ama ∞'ın bir girdisinin ∞'ın bir çıktısı olması gerekiyor mu?
user75200

Yanıtlar:


8

JavaScript (ES6), 52 bayt

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

Nasıl?

Aksine, açıkça işlem daha T i  = 1 + 2 + 3 + ... + i , Ki ile başlayan t = 0 ve yinelemeli çıkarma t + 1 den n ise t <n , artan t her tekrarda. Durumu artık yerine değilken, toplam T t çıkartıldığında n ve çıkış güncellenir. İşlemi n = 0 olana kadar tekrarlıyoruz.

Aşağıda n = 100 için yapılan tüm işlemlerin bir özeti verilmiştir .

 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"

Test senaryoları


5

Jöle , 18 17 bayt

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

Bu, STDOUT'a yazdırılan monadik bir bağlantıdır. Dönüş değeri 0'dır ve yok sayılmalıdır.

Çevrimiçi deneyin!


4

dc, 74 bayt

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

Bu çok kötü.

?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 bayt

@Arnauld sayesinde 4 bayt kaydedildi

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

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

@ Arnauld Oh vay, bu çok daha iyi. Kendiniz yayınlamalısınız ...
ETHproductions 2:17 '

1
Peki. Sürümünüzde, yapmak güvenli f=(n,p=q=0)ve olur f(n,++q+p)mu?
Arnauld

@Arnauld Evet, teşekkürler!
ETHproductions

2

Java 7, 81 bayt

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

Liman dan @Arnauld 'ın inanılmaz JavaScript (ES6) cevap .
Kendi yaklaşımım neredeyse 2 kat daha uzundu.

Burada deneyin.

Açıklama:

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 bayt

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

[Çevrimiçi deneyin!] (Test takımı içerir) Büyük harf kullanır. Düzenleme: @ MartinEnder'in cevabı utanmadan adapte ederek 70 74 bayt kaydedildi. Bu sayı üçgen mi? Açıklama: Sayı tek sayıya dönüştürülür, ardından sayı tükenene kadar mümkün olan en büyük üçgen sayı tekrarlanır. Her eşleşme daha sonra baz 36'a dönüştürülür.



0

R, 87 bayt

Başlangıçta, olası Üçgen sayıları önceden ayarlamaya çalıştım. Bu 105 bayt ile bu koda yol açtı:

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

Bu daha fazla indeksleme gerektirdi, bu yüzden baytları 87'ye düşürmek için @Arnauld'dan metodolojiyi denedim.

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

Her iki kod da önceden ayarlanmış harfleri kullandı, çünkü onların taban 36'ya dönüştürmek için kısa bir yol bulamadım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.