숫자 삼각형 뒤집기


30

양의 정수를 삼각형으로 나열한 다음 왼쪽에서 오른쪽으로 뒤집습니다. 숫자가 주어지면 보낸 숫자를 출력하십시오. 이것은 자기 역 매핑입니다.

         1                      1         
       2   3                  3   2       
     4   5   6    <--->     6   5   4     
   7   8   9  10         10   9   8   7   
11  12  13  14  15     15  14  13  12  11

A038722 의 n 번째 요소이며 인덱스는 다음과 같습니다.

1, 3, 2, 6, 5, 4, 10, 9, 8, 7, 15, 14, 13, 12, 11, ...

이 시퀀스는 길이가 증가함에 따라 양의 정수의 연속 된 청크를 반대로 바꿉니다.

 1, 3, 2, 6, 5, 4, 10, 9, 8, 7, 15, 14, 13, 12, 11, ...
<-><----><-------><-----------><------------------>

테스트 사례 :

1 -> 1
2 -> 3
3 -> 2
4 -> 6
14 -> 12
990 -> 947
991 -> 1035
1000 -> 1026
1035 -> 991
1036 -> 1081
12345 -> 12305

리더 보드 :

답변:



7

젤리 , 8 7 바이트

RṁR€UFi

1 바이트를 절약 해 준 @ErikTheOutgolfer에게 감사합니다!

온라인으로 사용해보십시오!

작동 원리

RṁR€UFi  Main link. Argument: n

R        Range; yield [1, ..., n].
  R€     Range each; yield [[1], [1, 2], [1, 2, 3], ..., [1, ..., n]].
 ṁ       Mold the left argument like the right one, yielding
         [[1], [2, 3], [4, 5, 6], ...]. The elements of the left argument are 
         repeated cyclically to fill all n(n+1)/2 positions in the right argument.
    U    Upend; reverse each flat array, yielding [[1], [3, 2], [6, 5, 4], ...].
     F   Flatten, yielding [1, 3, 2, 6, 5, 4, ...].
      i  Index; find the first index of n in the result.

6

Alice , 27 바이트

.C아이디어를 위한 Sp3000에 감사합니다 .

/o
\i@/.2:e2,tE*Y~Z.H2*~.C+

온라인으로 사용해보십시오!

설명

삼각형 숫자를 사용하여 이것을 계산하는 더 짧은 방법이있을 수 있다고 생각하지만 이것이 내장의 흥미로운 남용이라고 생각하므로 여기에 다른 해결책이 있습니다.

기본 아이디어는 Alice의 "pack"및 "unpack"내장 기능을 사용하는 것입니다. "Pack" Z또는는 두 개의 정수를 취하여 하나의 정수에 이차원 적으로 매핑합니다. "포장 풀기" Y또는는이 Bijection을 반전시키고 하나의 정수를 2로 바꿉니다. 일반적으로 정수 목록 또는 정수 트리를 단일 (큰) 정수로 저장하고 나중에 개별 값을 복구하는 데 사용할 수 있습니다. 그러나이 경우에는 반대 방향으로 함수를 사용하여 bijection의 본질이 작동하도록 할 수 있습니다.

하나의 정수를 두 개의 정수로 풀면 기본적으로 세 단계로 구성됩니다.

  1. 간단한 "접기"로 ℤ → ℕ (0 포함) 지도 . 즉, 음의 정수를 홀수 내츄럴에 매핑하고 음이 아닌 정수를 짝수 내츄럴에 매핑합니다.
  2. Cantor 페어링 기능을 사용하여 ℕ → ℕ 2를 매핑 합니다 . 즉, 내추럴은 무한 그리드의 대각선을 따라 작성되며 인덱스를 반환합니다.

       ...
    3  9 ...
    2  5 8 ...
    1  2 4 7 ...
    0  0 1 3 6 ...
    
       0 1 2 3
    

    8를 들어 쌍에 매핑됩니다 (1, 2).

  3. 각 정수에 대해 1 단계의 역수를 개별적으로 사용하여 2 → ℤ 2를 매핑 합니다. 즉, 홀수 내추럴은 음의 정수로 매핑되고 내추럴도 음이 아닌 정수로 매핑됩니다.

두 정수를 하나로 묶기 위해 각 단계를 반전시킵니다.

이제 Cantor 페어링 기능의 구조가 필요한 삼각형을 편리하게 인코딩한다는 것을 알 수 있습니다 (값은 하나씩이지만). 이러한 대각선을 반대로하려면 xy 좌표를 그리드로 바꾸면 됩니다.

불행하게도, 위의 세 단계 모두 단일 내장 Y(또는 Z) 으로 결합 되므로 ourselves → ℕ 또는 ℕ → ℤ 매핑을 직접 실행 취소해야합니다 . 그러나 이렇게하는 동안 테이블의 겉보기 오류를 처리하기 위해 + → ℤ 또는 ℤ → ℕ + 매핑 을 직접 사용하여 몇 바이트를 저장할 수 있습니다 . 전체 알고리즘은 다음과 같습니다.

  1. (n / 2) * (-1) n-1을 사용하여 + → ℤ 를 매핑 합니다. 이 매핑은 압축을 풀 때 묵시적 ℤ → ℕ 매핑을 취소하도록 선택됩니다 . 단, 값을 1 씩 내립니다.
  2. 결과를 두 개의 정수로 압축 해제하십시오.
  3. 그것들을 교환하십시오.
  4. 교체 된 값을 단일 정수로 다시 묶습니다.
  5. | 2n |를 사용하여 지도 ℤ → ℕ + + (n≥0) . 다시이 매핑은 값을 1 씩 올리는 것을 제외하고 패킹 중에 암시 적 ℕ → ℤ 매핑을 취소하도록 선택 됩니다.

그 방법으로 우리는 프로그램을 볼 수 있습니다.

/o
\i@/...

이것은 정수 입력 및 출력을 가진 선형 산술 프로그램을위한 프레임 워크입니다.

.    Duplicate the input.
2:   Halve it.
e    Push -1.
2,   Pull up the other copy of the input.
t    Decrement.
E    Raise -1 to this power.
*    Multiply. We've now computed (n/2) * (-1)^(n-1).
Y    Unpack.
~    Swap.
Z    Pack.
.H   Duplicate the result and take its absolute value.
2*   Double.
~    Swap with other copy.
.C   Compute k-choose-k. That's 1 for k ≥ 0 and 0 for k < 0.
+    Add. We've now computed |2n| + (n≥0).



4

옥타브 , 71 68 바이트

Conor O'Brien 덕분에 3 바이트가 절약되었습니다 .

x=triu(ones(n=input('')));x(~~x)=1:nnz(x);disp(nonzeros(flip(x))(n))

메모리 제한으로 인해 큰 입력에서는 작동하지 않습니다.

온라인으로 사용해보십시오!

설명

입력을 고려하십시오 n = 4. 코드는 먼저 행렬을 만듭니다.

 1     1     1     1
 0     1     1     1
 0     0     1     1
 0     0     0     1

그런 다음에 의해 (다음에 걸쳐, 아래) 열 주요 순서로 제로가 아닌 항목을 대체 1, 2, 3... :

 1     2     4     7
 0     3     5     8
 0     0     6     9
 0     0     0    10

그런 다음 행렬을 세로로 뒤집습니다.

 0     0     0    10
 0     0     6     9
 0     3     5     8
 1     2     4     7

마지막으로 ncolumn-major 순서에서 0이 아닌 -th 값을 취합니다 6. 이 경우에는입니다 .


1
@ rahnema1 e천재입니다! 다른 좋은 제안과 함께 답으로 게시해야합니다. 에 관해서는 ans =, 그것이 그것이 유효한지 확신하지 못합니다
Luis Mendo

4

하스켈 , 31 바이트

r=round
f n=r(sqrt$2*n)^2-r n+1

온라인으로 사용해보십시오!

이 답변은 수식을 사용합니다. 여기서 가장 흥미로운 답은 아니지만 가장 골치 거리가됩니다.

하스켈 , 38 36 34 바이트

x!y|x<=y=1-x|v<-y+1=v+(x-y)!v
(!0)

온라인으로 사용해보십시오!

(!0) 우리가 걱정하는 포인트 프리 기능입니다.

설명

이 답변에 매우 만족한다고 말하면서 시작하겠습니다.

여기서 기본 아이디어는 입력보다 작은 가장 큰 삼각 수를 제거하면 역 삼각형을 다시 추가 할 수 있다는 것입니다. 우리는 연산자를 정의 그래서 !, !우리의 일반 입력을 취 x뿐만 아니라 여분의 수를합니다 y. y증가하는 삼각형 수의 크기를 추적합니다. 경우 x>y우리는 재귀하려는, 우리는 감소 x에 의해 y및 증가 y하나. 그래서 우리는 그것을 계산 (x-y)!(y+1)하고 추가 y+1합니다. 경우 x<=y우리는 우리의 기본 케이스에 도달 한 반전하는 x우리가 돌아 삼각형의 행에서의 위치를 1-x.

하스켈 , 54 바이트

f x|u<-div(x^2-x)2=[u+x,u+x-1..u+1]
(!!)$0:(>>=)[1..]f

온라인으로 사용해보십시오!

(!!)$0:(>>=)[1..]f 포인트없는 기능입니다

설명

우리가이다에 관심을 제일 먼저 f, f받는 함수입니다 x및 반환 x역으로 일 삼각형 번째 행을. 먼저 두 x-1번째 삼각 수를 계산 하고에 할당 하여이 작업을 수행 u합니다. u<-div(x^2-x)2. 그런 다음 목록을 반환합니다 [u+x,u+x-1..u+1]. u+xx삼각형의 숫자이고 행의 첫 번째 숫자 u+x-1는 그보다 하나가 작고 행 의 두 번째 숫자 u+1는 마지막 삼각형의 숫자보다 하나 더 많으므로 행의 마지막 숫자입니다.

일단 우리가 삼각형을 평평하게 f하는리스트 (>>=)[1..]f를 만들었습니다. 우리는 앞에 0을 추가하여 0:답이 1로 오프셋되지 않도록하고 색인 함수에 제공 (!!)합니다.

하스켈 , 56 바이트

f 0=[0]
f x|u<-f(x-1)!!0=[u+x,u+x-1..u+1]
(!!)$[0..]>>=f

온라인으로 사용해보십시오!

이것은 2 바이트 더 길지만 제 생각에는 조금 더 우아합니다.


3

C (gcc) , 48 바이트

k,j,l;f(n){for(k=j=0;k<n;)l=k,k+=++j;n=1+k-n+l;}

온라인으로 사용해보십시오!

아마도 차선책 일 수도 있지만 이것에 매우 만족합니다. 사실을 사용

NTF N = T N + A057944 ( N ) -N + 1

(내가 공식을 올바르게 적어 놓으면 바로 그 것입니다.)


return을 호출하지 않지만 반환 값이 사용됩니다. 그것은 정의되지 않은 동작입니다.
2501

@ 2501 프로그램이 작동하는 한 허용됩니다. 그리고 함수의 첫 번째 인수에 쓰는 것은 값을 반환하는 것과 같습니다.
Conor O'Brien

그리고 함수의 첫 번째 인수에 쓰는 것은 값을 반환하는 것과 같습니다. C 언어에는 그런 것이 없습니다. 표준은 명시 적으로 반환하지 않는 함수의 반환 값을 사용하는 것은 정의되지 않은 동작이라고 말합니다.
2501

1
@ 2501 C 사양에 대해 C 환경 (gcc)을 혼동하는 것 같습니다. 예, C 언어 / 스펙은이를 정의되지 않은 것으로 부르지 만 그렇게 구현됩니다. 따라서 "동등한"이라고 말할 때 gcc와 대부분의 다른 컴파일러에 의한 C 구현을 가장 확실하게 언급하고 있습니다. PPCG에서는 "완벽한"코드를 작성하지 않습니다. 대부분의 코드는 골프를위한 사양에 맞지 않습니다. 내가 말했듯이, 그것이 작동하는 한 유효한 대답입니다.
Conor O'Brien

2501 @ 나는 메타 사이트, 특히 몇 가지 기사를 읽어 보시기 바랍니다 이 하나 .
Conor O'Brien

2

05AB1E , 30 바이트

U1V[YLO>X›iYLOX-UY<LO>X+,q}Y>V

온라인으로 사용해보십시오!


"무엇입니까? 유니 코드가없는 05AB1E 답변?" 그러나 ASCII가 아닌 캐릭터 하나가 그것을 망칩니다 ... : P 멋진 첫 번째 대답은 프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다!
clismique

@ Qwerp-Derp 대단히 감사합니다! 방금이 언어를 배우기 시작했기 때문에 제 대답이 그렇게 나쁘다는 것에 놀라지 않습니다.
Eduardo Hoefel

2

껍질 , 6 바이트

!ṁ↔´CN

온라인으로 사용해보십시오!

설명

!ṁ↔´CN  -- implicit input N, for example: 4
   ´ N  -- duplicate the natural numbers:
           [1,2,3,…] [1,2,3,…]
    C   -- cut the second argument into sizes of the first:
           [[1],[2,3],[4,5,6],[7,8,9,10],…]
 ṁ↔     -- map reverse and flatten:
           [1,3,2,6,5,4,10,9,8,7,15,…
!       -- index into that list:
           6

2

tinylisp , 78 바이트

(d _(q((R N T)(i(l T N)(_(a R 1)N(a T R))(a 2(a T(s T(a N R
(d f(q((N)(_ 2 N 1

f매핑을 수행 하는 함수 를 정의합니다 . 온라인으로 사용해보십시오!

언 골프

입력 숫자보다 크거나 같은 가장 작은 삼각형 숫자와 숫자가있는 삼각형의 행을 찾습니다.이 숫자에서 뒤집힌 버전을 계산할 수 있습니다.

  • 현재 삼각형 숫자가 N보다 작은 경우 삼각형의 다음 행으로 반복합니다. (수학을 단순화하기 위해 상단 행을 2 행으로 취급합니다.)
  • 그렇지 않으면, 뒤집힌 N 버전은 (TN) + (TR) +2입니다.

메인 함수 는 상단 행부터 시작 flip하여 도우미 함수 를 호출합니다 _flip.

(load library)

(def _flip
 (lambda (Num Row Triangular)
  (if (less? Triangular Num)
   (_flip Num (inc Row) (+ Triangular Row))
   (+ 2
    (- Triangular Num)
    (- Triangular Row))))))

(def flip
 (lambda (Num) (_flip Num 2 1)))

1

05AB1E , 9 바이트

·LD£í˜¹<è

온라인으로 사용해보십시오!

설명

·L          # push range [1 ... 2n]
  D         # duplicate
   £        # split the first list into pieces with size dependent on the second list
    í       # reverse each sublist
     ˜      # flatten
      ¹<è   # get the element at index <input>-1

불행하게도 배열 병합은 큰 목록을 잘 처리하지 못합니다.
1 바이트의 비용 으로 OEIS 에서 찾은 수학 공식을 사용하여 · t2z + ïn¹-> 을 수행 할 수 있습니다.floor(sqrt(2*n)+1/2)^2 - n + 1


1

배치, 70 바이트

@set/ai=%2+1,j=%3+i
@if %j% lss %1 %0 %1 %i% %j%
@cmd/cset/ai*i+1-%1

루프를 사용하여 최소 개수만큼의 삼각 숫자 색인을 찾습니다 n.





0

J, 25 바이트

3 :'>:y-~*:>.-:<:%:>:8*y'

설명으로을 고려하십시오 f(n) = n(n+1)/2. f(r), 행이 주어지면 대칭 삼각형 r의 세 r번째 행의 가장 왼쪽 숫자를 반환합니다 . 이제 고려하십시오 g(n) = ceiling[f⁻¹(n)]. g(i)index가 주어지면 i인덱스 i가있는 행을 반환합니다. 그런 다음 f(g(n))인덱스 n이있는 행의 가장 왼쪽 번호를 반환합니다. 그래서, h(n) = f(g(n)) - (n - f(g(n)-1)) + 1위의 문제에 대한 답이다.

단순화하면 얻을 수 h(n) = [g(n)]² - n + 1 = ceiling[(-1 + sqrt(1 + 8n))/2]² - n + 1있습니다.

@Arnauld의 공식에서 다음과 같이 나타납니다.

ceiling[(-1 + sqrt(1 + 8n))/2] = floor[1/2 + sqrt(2n)].


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