Nicomachus의 정리를 시각화


35

Nichomachus의 정리는 합의 제곱을 큐브의 합과 관련시킵니다.

니코 마커스의 정리

아름다운 기하학적 시각화 기능이 있습니다.

심상

과제 :이 시각화의 2D 부분을 ASCII로 작성하십시오.

다이어그램이 모든 시각적 경계를 유지하도록해야합니다. 4 가지 "색상"으로 가장 간단하지만 3 가지만으로도 가능합니다 (아래 마지막 예 참조). 4 가지 색상을 사용하면 "스트립"내의 영역 (예 : 단일 큐브를 구성하는 다른 부분)을 구별하기 위해 2 개를 사용하고 인접한 스트립을 구별하기 위해 2 개를 사용합니다. 원하는 경우 4 가지 이상의 색상을 사용할 수도 있습니다. 이 중 하나라도 혼란 스러우면 아래 예제 출력이 명확해야합니다.

입출력

입력은 0보다 큰 단일 정수입니다. 출력은 위의 이미지에서 해당 입력 번호에 대한 병합 된 그리드에 해당하는 아래 예와 유사한 ASCII 그리드입니다. 선행 및 후행 공백은 괜찮습니다.

이것은 표준 규칙을 가진 코드 골프입니다.

샘플 출력

N = 1

#

N = 2

#oo   
o@@   
o@@   

N = 3

#oo+++
o@@+++
o@@+++
+++###
+++###
+++###

N = 4

#oo+++oooo
o@@+++oooo
o@@+++@@@@
+++###@@@@
+++###@@@@
+++###@@@@
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo

N = 5

#oo+++oooo+++++
o@@+++oooo+++++
o@@+++@@@@+++++
+++###@@@@+++++
+++###@@@@+++++
+++###@@@@#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++

@BruceForte 덕분에 N = 4의 3 가지 컬러 버전 :

#oo+++oooo
o##+++oooo
o##+++####
+++ooo####
+++ooo####
+++ooo####
oo####++++
oo####++++
oo####++++
oo####++++

6
4 가지 색 정리 : D
Leaky Nun

1
N = 5에 대한 출력을 추가 할 수 있습니까?
Uriel

1
@ 우리엘 완료. 내 편집을 참조하십시오.
요나

감사! 또한 @와 os를 N = 4의 외부 스트립에서만 전환 할 수 있습니까? 또는 출력이 이러한 텍스트를 다른 문자 집합으로 엄격하게 대체해야합니까?
우리엘

@Uriel 전환은 괜찮습니다. 중요한 것은 인접한 색상이 충돌하지 않기 때문에 패턴이 보입니다.
요나

답변:


17

MATL , 30 28 27 바이트

t:P"@:s:@/Xk&+@+8MPt&(]30+c

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

보너스 기능 :

  • 들어 26 바이트 , 다음과 같은 수정 된 버전은 생산 그래픽 출력을 :

    t:P"@:s:@/Xk&+@+8MPt&(]1YG
    

    MATL Online 에서 사용해보십시오 !

  • 이미지가 약간의 색상 을 요구하고 있으며 7 바이트 만 소요됩니다.

    t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG
    

    MATL Online 에서 사용해보십시오 !

  • 또는 더 긴 버전 (37 바이트)을 사용하여 문자 행렬이 점차 어떻게 구축 되는지 확인하십시오 .

    t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c
    

    MATL Online 에서 사용해보십시오 !

출력 예

input is 8의 경우 다음은 기본 버전, 그래픽 출력 및 컬러 그래픽 출력을 보여줍니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

설명

일반 절차

숫자 형 매트릭스는 외부 레이어에서 내부 레이어로 N단계적으로 구성되며 N입력 위치 입니다. 각 단계는 이전 행렬의 내부 (왼쪽 위) 부분을 덮어 씁니다. 결국, 얻어진 행렬의 숫자는 문자로 변경됩니다.

입력을 4위해 첫 번째 행렬은

10 10  9  9  9  9  8  8  8  8
10 10  9  9  9  9  8  8  8  8
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6

두 번째 단계로 매트릭스

7 7 7 6 6 6
7 7 7 6 6 6
7 7 7 6 6 6
6 6 6 5 5 5
6 6 6 5 5 5
6 6 6 5 5 5

후자의 상반부에 덮어 씁니다. 그런 다음 동일하게 수행됩니다.

6 5 5
5 4 4
5 4 4

그리고 마지막으로

3

결과 행렬은

3 5 5 6 6 6 8 8 8 8
5 4 4 6 6 6 8 8 8 8
5 4 4 6 6 6 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6

마지막으로 30각 항목에 추가되고 결과 숫자는 코드 포인트로 해석되어 문자로 변환됩니다 (따라서 시작하여 33에 해당 !).

중간 행렬의 구성

입력의 N경우 값을 k에서 N로 줄이는 것을 고려하십시오 1. 각각 k으로부터 정수 벡터 1에이 k*(k+1)발생하고, 각 항목으로 나누어 k과 올림. 예를 들어, 이것에 대해 k=4(모든 블록은 k마지막 블록을 제외하고 크기가 있습니다 ) :

1 1 1 1 2 2 2 2 3 3

반면 k=3결과는 다음과 같습니다 (모든 블록의 크기는 k다음과 같습니다).

1 1 1 2 2 2

이 벡터는 브로드 캐스트와 함께 요소별로 전치 된 사본에 추가됩니다. 그런 다음 k각 항목에 추가됩니다. 대한 k=4이 있습니다

6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
8  8  8  8  9  9  9  9 10 10
8  8  8  8  9  9  9  9 10 10

이것은 가로 및 세로로 뒤집힌 것을 제외하고는 위에 표시된 중간 행렬 중 하나입니다. 따라서 남은 것은이 행렬을 뒤집어 지금까지 "누적 된"행렬의 왼쪽 상단 모서리에 쓰고 첫 번째 k=N단계 ( ) 의 빈 행렬로 초기화하는 것입니다.

암호

t       % Implicitly input N. Duplicate. The first copy of N serves as the
        % initial state of the "accumulated" matrix (size 1×1). This will be 
        % extended to size N*(N+1)/2 × N*(N+1)/2 in the first iteration
 :P     % Range and flip: generates vector [N, N-1, ..., 1]
"       % For each k in that vector
  @:    %   Push vector [1, 2, ..., k]
  s     %   Sum of this vector. This gives 1+2+···+k = k*(k+1)/2
  :     %   Range: gives vector [1, 2, ..., k*(k+1)/2]
  @/    %   Divide each entry by k
  Xk    %   Round up
  &+    %   Add vector to itself transposed, element-wise with broadcast. Gives
        %   a square matrix of size k*(k+1)/2 × k*(k+1)/2
  @+    %   Add k to each entry of the this matrix. This is the flipped
        %   intermediate matrix
  8M    %   Push vector [1, 2, ..., k*(k+1)/2] again
  Pt    %   Flip and duplicate. The two resulting, equal vectors are the row and
        %   column indices where the generated matrix will be written. Note that
        %   flipping the indices has the same effect as flipping the matrix
        %   horizontally and vertically (but it's shorter)
  &(    %   Write the (flipped) intermediate matrix into the upper-left
        %   corner of the accumulated matrix, as given by the two (flipped)
        %   index vectors 
]       % End
30+     % Add 30 to each entry of the final accumulated matrix
c       % Convert to char. Implicitly display

MATL을 전혀 모르지만 30을 추가하고 문자로 변환하는 대신 mod10을 사용하여 바이트를 절약 할 수 있습니까?
user2390246

또는 심지어 mod4 ...
user2390246

@ user2390246 숫자를 한 자리수로 유지하고 char로 변환하지 않으시겠습니까? 숫자 매트릭스는 숫자 사이에 공백으로 인쇄되기 때문에 작동하지 않습니다. 그러나 어쨌든 아이디어에 감사드립니다 :-)
Luis Mendo

충분합니다. n> 226은 어떻게됩니까? 유효한 문자 범위를 벗어나지 않습니까? (I는 확인하지 못했습니다 당연히, TIO에 시간 초과, 그래서)
user2390246

@ user2390246 예, 높은 입력 번호의 경우 외부로 이동합니다. ASCII 문자를 고려하면 최대 코드 포인트는 127이므로 더 빨리 밖에 나갑니다. 그러나 그 전에 메모리가 부족하다는 것을 알았습니다 (문자 행렬이 너무 큽니다). 어쨌든, 메모리 또는 데이터 유형 제한으로 인해 주어진 입력 크기까지만 작업하는 것이 일반적으로 허용됩니다.
Luis Mendo

7

파이썬 2 , 187 (178) 164 162 152 바이트

Xcoder 덕분에 -8 바이트,
Stephen 덕분에 -1 바이트,
Jonathan Frech 덕분에 -10 바이트

g=lambda y:y>1and[l+y*f(y,i)for i,l in enumerate(g(y-1))]+y*[''.join(f(y,i)for i in range(y*-~y/2))]or['#']
f=lambda y,i:'0@+#'[(y*~-y/2%y+i)/y%2+y%2*2]

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


집에 도착하면 179 바이트 입니다.
Mr. Xcoder

@ Mr.Xcoder 178 바이트
Stephen

1
재귀 적으로 사용할 때, 즉 나머지 코드에서 이름을 사용하는 경우 람다 함수의 이름 바이트 수를 포함시킬 수 없습니까?
Jonathan Frech

sum(range(y))%y->y*~-y/2%y
Jonathan Frech

@JonathanFrech 예, 재귀 할 때는 반드시 있어야합니다.
Rod

7

, 50 46 바이트

F⮌…·¹N«≔⊘×ι⊕ιθF⊕⊘ι«F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명이있는 이전 50 바이트 버전 : 온라인으로 사용해보십시오!

F⮌…·¹N«≔÷×ι⁺¹ι²θF⁺¹÷鲫F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

F     «     Loop over
  …·¹       Inclusive range from 1 to
     N      Input as a number
 ⮌          Reversed

   ι⁺¹        Add 1 to current index
  ×   ι       Multiply by current index
 ÷     ²      Divide by 2
≔       θ     Assign to q

F     «      Loop over
             Implicit range from 0 to
   ÷ι²       Half the current index
 ⁺¹          Plus 1

F       «    Loop over
  #+@        Literal string
 §           Circularly indexed by
     ⁺ικ     Sum of outer and inner index

    ×ικ     Multiply outer and inner index
  ⁻θ        Subtract from q
UO     θλ   Draw an oblong (q-ik, q) using that character

UOθ⁻θ×ικλ   Draw an oblong (q, q-ik) using that character

참고 : l문자열 인덱싱 결과를 Charcoal의 모호한 구성이므로 변수에 직접 할당 할 수 없기 때문에 문자를 직접 할당하지 않고 문자를 반복 합니다. 다행히 바이트 수는 동일합니다.


기술적으로 인수 순서가 역전되므로 ASCII 변수를 사용하여 수행 할 수 있습니다 (아직도 덜 골치이므로 액세스해야하는 연산자가 필요합니다)
ASCII 전용

5

C (GCC) , 135 (128) 120 바이트

f(n,m,i,x,y,k){for(m=n*-~n/2,i=m*m;i--;printf("\n%d"+!!(~i%m),(x/k+y/k+k)%3))for(x=i%m,y=i/m,k=n;x>=k&y>=k;x-=k--)y-=k;}

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

세 가지 색상 만 사용합니다.

개념적으로 180도 회전 된 그리드에서 작동합니다.

000111
000111
000111
111220
111220
111001

그리고 공식에 따라 색상을 계산합니다.

c(x,y,n) = c(x-n,y-n,n-1)                   if x >= n and y >= n
         = (x div n + y div n + n) mod 3    otherwise


@JonathanFrech 유효하지 않은 C이며로 끝납니다 gcc -O2.
nwellnhof

충분히 공평합니다. 모듈러스 3 ( g(i%m,i/m,n)%3) 때문에 두 번째 코드가 세 가지 색상에서만 작동 할 수 있습니까?
Jonathan Frech

x/k&&y/k대신 추천x>=k&y>=k
천장 고양이

2

R , 131 (126) 123 바이트

@Giuseppe 덕분에 3 바이트 절약

function(n){l=w=sum(1:n)
m=matrix(,l,l)
for(i in n:1){m[l:1,l:1]=outer(x<-(1:l-1)%/%i,x,`+`)+i
l=l-i}
write(m%%4,"",w,,"")}

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

이것은 @LuisMendo의 MATL 답변 과 동일한 알고리즘을 사용합니다 . 유일한 차이점은 문자로 변환하는 대신 각 요소가 단일 ASCII 문자임을 보장하기 위해 모든 값 mod4와 함께 행렬이 출력된다는 것입니다.


1
123 바이트! for루프를 -1 바이트로 다시 가져 왔습니다 :)
Giuseppe

1

파이썬 2 , 176175 바이트

n=input()
R,J=range,''.join;r=[]
for i in R(n+1):
 S=sum(R(i));c='AxBo'[i%2::2]
 for j in R(S):r[~j]+=c[j/i%2]*i
 r+=[J(c[-j/i%2]for j in R(S+i,0,-1))]*i
for l in r:print J(l)

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


J="".join;(+10 바이트) 를 정의 하고 "".joins (-2 * 7 = -14 바이트)를 J(+2 바이트)로 바꾸면 바이트를 저장할 수 있습니다 ( print; +1 바이트 뒤에 추가 공간이 있어야 함). .
Jonathan Frech
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.