숫자를 삼각형으로 분해


15

정수 n이 주어지면 다음 과 같이 최대 삼각 수의 합으로 분해합니다 (여기서 T mm 번째 삼각 수 또는 1에서 m 사이의 정수의 합을 나타냄).

  • n> 0 인 동안

    • 가장 큰 가능한 삼각형 번호 찾기 T의 m을 하도록 T의 m ≤ N .

    • n 의 삼각 분해 표현에 m 을 추가하십시오 .

    • n 에서 T m 을 뺍니다 .

예를 들어 44를 입력 하면 다음과 같은 이유로 출력 8311이됩니다 .

  • 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36 <44이지만 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45> 44입니다.

    • 첫 번째 숫자는 8입니다 . 44에서 36을 빼면 8이 남습니다.
  • 1 + 2 + 3 = 6 <8이지만 1 + 2 + 3 + 4 = 10> 8.

    • 두 번째 숫자는 3입니다 . 8에서 6을 빼면 2가 남습니다.
  • 1 <2이지만 1 + 2 = 3> 2.

    • 세 번째와 네 번째 숫자는 11 이어야합니다 .

1에서 9까지의 숫자를 사용하여 첫 번째 9 개의 삼각형 숫자를 표시 한 다음 문자 a에서 z (대문자 또는 소문자)를 사용하여 10 번째에서 35 번째 삼각형 숫자를 나타냅니다. 더 큰 "숫자"를 사용해야하는 입력은 절대 제공되지 않습니다.

입력의 경계는 1 ≤ n <666 이며 항상 정수입니다.

가능한 모든 입력 및 출력 및 일부 선택된 테스트 사례 (입력, 출력으로 나열 됨) :

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

-1/12 의 입력에 대해 의 출력이 필요하지 않습니다. :)


그러나 의 입력은 의 출력을 가져야합니까?
user75200

답변:


8

자바 스크립트 (ES6), 52 바이트

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

어떻게?

오히려 명시 적 계산보다 T가 나는  = 1 + 2 + 3 + ... + 난 우리가 시작 t = 0 반복적 빼기 t + 1 에서 N 하면서 t는 <N , 증가하는 t를 각각의 반복에서. 더 이상 조건이 충족되지 않으면 n 에서 총 T t 가 차감되고 그에 따라 출력이 업데이트됩니다. n = 0 까지 프로세스를 반복합니다 .

다음은 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"

테스트 사례



4

dc, 74 바이트

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

이것은 끔찍하다.

?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

자바 스크립트 (ES6), 61 57 바이트

@Arnauld 덕분에 4 바이트 절약

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

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

@Arnauld 오 와우, 그게 더 나아. 직접 게시해야합니다 ...
ETHproductions

1
좋구나. 버전에서는 안전 할 것 f=(n,p=q=0)f(n,++q+p)?
Arnauld

@Arnauld 네, 감사합니다!
ETHproductions

2

자바 7, 81 바이트

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

@Arnauld 의 놀라운 JavaScript (ES6) 답변의 포트 .
내 자신의 접근 방식은 거의 2 배 길었습니다.

여기에서 시도하십시오.

설명:

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

망막 , 115 (108) 38 34 바이트

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

[온라인으로 사용해보십시오!] (테스트 스위트 포함) 대문자를 사용합니다. 편집 : @MartinEnder의 대답을 부끄럽게 적용하여 70 74 바이트를 절약했습니다. 이 숫자는 삼각형입니까? 설명 : 숫자가 단항으로 변환 된 후 숫자가 소진 될 때까지 가능한 가장 큰 삼각형 숫자가 반복적으로 일치됩니다. 그런 다음 각 경기는 기본 36으로 변환됩니다.



0

R, 87 바이트

원래 가능한 삼각형 숫자를 미리 설정하려고했습니다. 이것은 105 바이트 의이 코드로 이어졌습니다.

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

더 많은 인덱싱이 필요했기 때문에 @Arnauld의 방법론을 사용하여 바이트를 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})

두 코드 모두 사전 설정 문자를 사용했습니다.베이스 36으로 변환하는 짧은 방법을 찾을 수 없기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.