Phân tách một số thành hình tam giác


15

Cho một số nguyên n , phân tách nó thành một tổng các số tam giác cực đại (trong đó T m đại diện cho số tam giác thứ m hoặc tổng các số nguyên từ 1 đến m ) như sau:

  • trong khi n> 0 ,

    • tìm số tam giác lớn nhất có thể T m sao cho T m ≤ n .

    • nối m vào biểu diễn phân rã tam giác của n .

    • trừ T m từ n .

Ví dụ: đầu vào 44 sẽ mang lại đầu ra 8311 , bởi vì:

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

    • chữ số đầu tiên là 8 ; trừ 36 từ 44 để có 8 còn lại.
  • 1 + 2 + 3 = 6 <8, nhưng 1 + 2 + 3 + 4 = 10> 8.

    • chữ số thứ hai là 3 ; trừ 6 từ 8 để có 2 dư.
  • 1 <2, nhưng 1 + 2 = 3> 2.

    • chữ số thứ ba và thứ tư phải là 11 .

Sử dụng các chữ số từ 1 đến 9 để thể hiện 9 số tam giác đầu tiên, sau đó sử dụng các chữ cái từ a đến z (có thể viết hoa hoặc viết thường) để biểu thị số tam giác thứ 10 đến 35. Bạn sẽ không bao giờ được cung cấp một đầu vào sẽ yêu cầu sử dụng một "chữ số" lớn hơn.

Giới hạn trên đầu vào là 1 ≤ n <666 và nó sẽ luôn là một số nguyên.

Tất cả các đầu vào và đầu ra có thể , và một số trường hợp thử nghiệm được chọn (được liệt kê là đầu vào, sau đó đầu ra):

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

Một sản phẩm của cho một đầu vào của -1/12 là không cần thiết. :)


Nhưng liệu một đầu vào của cần phải có một sản lượng ∞?
dùng75200

Câu trả lời:


8

JavaScript (ES6), 52 byte

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

Làm sao?

Thay vì tính toán rõ ràng T i  = 1 + 2 + 3 + Sự + i , chúng tôi bắt đầu với t = 0 và lặp lại trừ t + 1 từ n trong khi t <n , tăng t ở mỗi lần lặp. Khi điều kiện không được đáp ứng nữa, tổng cộng T t đã bị trừ khỏi n và đầu ra được cập nhật tương ứng. Chúng tôi lặp lại quá trình cho đến khi n = 0 .

Dưới đây là tóm tắt của tất cả các hoạt động cho 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"

Các trường hợp thử nghiệm



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

Điều này thật kinh khủng.

?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

Đã lưu 4 byte nhờ @Arnauld

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

1
Tôi đã cóf=(n,t=0)=>n?t+1>n?t.toString(36)+f(n):f(n-++t,t):1
Arnauld

@Arnauld Oh wow, đó là cách tốt hơn. Bạn nên tự đăng nó ...
ETHproductions

1
Ổn thỏa. Trong phiên bản của bạn, nó có an toàn để làm f=(n,p=q=0)f(n,++q+p)?
Arnauld

@Arnauld Vâng, cảm ơn!
Sản phẩm ETH

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):"");}

Cổng từ @Arnauld JavaScript (ES6) câu trả lời tuyệt vời 's .
Cách tiếp cận của riêng tôi dài gần gấp đôi ..

Hãy thử nó ở đây.

Giải trình:

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

Võng mạc , 115 108 38 34 byte

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

[Dùng thử trực tuyến!] (Bao gồm bộ kiểm tra) Sử dụng chữ in hoa. Chỉnh sửa: Đã lưu 70 74 byte bằng cách thích nghi với câu trả lời của @ MartinEnder cho số này có phải là hình tam giác không? Giải thích: Số được chuyển đổi thành đơn nguyên, sau đó số tam giác lớn nhất có thể được lặp lại cho đến khi hết số. Mỗi trận đấu sau đó được chuyển đổi thành cơ sở 36.



0

R, 87 byte

Ban đầu, tôi đã cố gắng đặt trước các số tam giác có thể. Điều này dẫn đến mã này với 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})

Điều này đòi hỏi phải lập chỉ mục nhiều hơn vì vậy tôi đã thử phương pháp luận từ @Arnauld để giảm các byte xuống còn 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})

Cả hai mã đều sử dụng các chữ cái đặt trước, vì chúng không thể tìm thấy một cách ngắn để chuyển đổi sang cơ sở 36.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.