이진 트리 프랙탈


25

오늘날의 과제는 이 예제와 같이 이진 트리 를 아름다운 로 그리는 것입니다 .

                               /\
                              /  \
                             /    \
                            /      \
                           /        \
                          /          \
                         /            \
                        /              \
                       /                \
                      /                  \
                     /                    \
                    /                      \
                   /                        \
                  /                          \
                 /                            \
                /                              \
               /\                              /\
              /  \                            /  \
             /    \                          /    \
            /      \                        /      \
           /        \                      /        \
          /          \                    /          \
         /            \                  /            \
        /              \                /              \
       /\              /\              /\              /\
      /  \            /  \            /  \            /  \
     /    \          /    \          /    \          /    \
    /      \        /      \        /      \        /      \
   /\      /\      /\      /\      /\      /\      /\      /\
  /  \    /  \    /  \    /  \    /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

입력으로 양의 정수가 제공됩니다. 이 입력은 나무높이입니다 . 위의 예는 높이가 6입니다.

전체 프로그램 또는 기능을 제출할 수 있으며 기본 IO 방법을 자유롭게 사용할 수 있습니다 . 예를 들어, 트리를 인쇄하고, 줄 바꿈으로 문자열을 반환하고, 2d char 배열을 반환하고, 트리를 파일에 저장하는 등의 작업이 모두 허용됩니다.

각 줄의 후행 공백이 허용됩니다.

다음은 입력 및 해당 출력의 몇 가지 예입니다.

1:
/\

2:
 /\
/\/\

3:
   /\
  /  \
 /\  /\
/\/\/\/\

4:
       /\
      /  \
     /    \
    /      \
   /\      /\
  /  \    /  \
 /\  /\  /\  /\
/\/\/\/\/\/\/\/\

5:
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

불행히도 결과는 기하 급수적으로 증가하므로 더 큰 예제를 보여주기는 어렵습니다. 다음은 8의 출력에 대한 링크 입니다.

평소와 같이 이것은 과제이므로 표준 허점이 적용되며 원하는 언어로 가능한 가장 짧은 프로그램을 작성하십시오.

행복한 골프!


모든 줄을 같은 길이로 만들기 위해 후행 공백이 있습니까?
xnor

@xnor 예, 좋습니다.
DJMcMayhem

답변:


5

파이썬 2, 77 바이트

S=s=i=2**input()
while s:print S/s*('/'+' '*(s-i)+'\\').center(s);i-=2;s/=s/i

후행 공백으로 인쇄하고 오류로 종료합니다.

이 코드를 제출 한Anarchy Golf 에서 제기 한 도전 과제 와 xsot에서 발견 한 1 바이트 개선 사항 에이 코드를 사용 했습니다 . 128의 하드 코드 된 값이로 변경되었습니다 2**input().

아이디어는 출력의 각 행이 한 번 이상 복사 된 세그먼트라는 것입니다. 입력 분할 후 절반에는 각 세그먼트의 사본이 하나씩 있고 다음 분할 후 분기에는 두 개의 사본이 /\있습니다.

각 세그먼트가 있었다 /\사이뿐만 아니라 적절한 길이 패드의 외측에 공백. 외부 패딩은로 수행됩니다 center.

변수 s는 각 세그먼트의 전류를 추적하며 세그먼트 수 S/s는 전체 너비가 트리 너비 가 되도록합니다 S. 줄 번호 i는 2로 카운트 다운되며 값 s이 절반 일 때마다 분할이 발생하고 세그먼트 폭이 반으로 줄어 듭니다 . 이것은 표현식을 통해 수행됩니다 s/=s/i. 에 i도달 0하면 프로그램을 종료하는 오류가 발생합니다.

anagolf는 프로그램 제출 만 허용하므로 재귀 함수의 가능성을 탐색하지 않았으므로 더 짧을 것으로 생각됩니다.



4

캔버스 , 11 바이트

/║╶╷[l\;∔↔║

여기 사용해보십시오!

설명:

/║          push `/\` ("/" palindromized so this is a Canvas object)
  ╶╷[       repeat input-1 times
     l        get the width of the ToS
      \       create a diagonal that long
       ;∔     prepend that to the item below
         ↔    reverse the thing horizontally
          ║   and palindromize it horizontally

3

하스켈 , 140 (138) 135 바이트

e n=[1..n]>>" "
n!f=(e n++).(++e n)<$>f
f 0=[]
f n=1!f(n-1)++['/':e(2*n-2)++"\\"]
b n|n<2=f 1|t<-b$n-1,m<-2^(n-2)=m!f m++zipWith(++)t t

온라인으로 사용해보십시오! 로 호출하고 b 5문자열 목록을 반환합니다.

예쁜 인쇄 사용법 :

*Main> putStr . unlines $ b 5
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

(일부) 설명 :

  • e nn공백 문자열을 생성 합니다
  • n!f문자열 목록에서 각 문자열을 왼쪽과 오른쪽 f으로 n공백 으로 채 웁니다.
  • f nA의는 "피크"을 그립니다 n의해 2n직사각형
  • b n 작은 나무 두 개를 연결하여 이진 트리를 그립니다.

편집 : Zgarb 덕분에 -3 바이트!


생각 1!f(n-1)하고 m!f m몇 바이트를 저장해야합니다.
Zgarb

@Zgarb 지적 해 주셔서 감사합니다. 우선 순위 규칙이 때때로 혼란스러워집니다.
Laikoni

2

J , 49 43 42 바이트

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))

숫자를 가져와 2D 문자형 배열을 반환하는 동사로 평가됩니다. 온라인으로 사용해보십시오!

설명

먼저 보조 동사를 반복하여 값 -1, 0 및 1의 행렬을 구성한 다음 숫자를 문자로 바꿉니다. 보조 동사는 다음 반복의 오른쪽 절반을 구성한 다음 수평으로 미러링하여 나머지를 생성합니다. 다음 설명에서는 ,2D 배열을 세로로 연결하고 1D 배열을 가로로 연결합니다.

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))  Input is n.
                          ^:(            )  Iterate this verb
                             <:             n-1 times
                               `(       )   starting from
                                    ,&*-    the array 1 -1 (actually sign(n), sign(-n))
                                 ,:@        shaped into a 1x2 matrix:
                                             Previous iteration is y.
                      #                      Take height of y,
                   i.@                       turn into range
                 =@                          and form array of self-equality.
                                             This results in the identity
                                             matrix with same height as y.
                       ,-                    Concatenate with -y, pad with 0s.
       (    )"1@(        )                   Then do to every row:
        |.,-                                 Concatenate reversal to negation.
' /\'{~                                     Finally index entry-wise into string.

1

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

f=n=>n<2?"/\\":" "+f(n-1).split`/`[0].replace(/|/g,"$`$'$'/$`$`\\$'$'$` \n")+f(n-1).replace(/.*/g,"$&$&")

기본 사례에서 결과를 재귀 적으로 구축하여 작동합니다 /\. 아래쪽 절반은 각 행이 복제 된 이전 사례입니다. 상반신은 조금 까다로웠다. 마치 앞의 경우를 원하고 양면 만 유지하려는 것처럼 보이지만 너비를 두 배로 늘리기 위해 문자열을 채우는 것에 대해 걱정해야하므로 대신 정규식 마술을 사용하십시오. 이전 사례에서 선행 공백을 가져와 모든 지점에서 분할함으로써 해당 지점 전후의 공간을 고려할 수 있습니다. 각 경기에서 1 씩 증가하기 전의 공백과 1 씩 감소한 후의 공백; 이것은 /\올바른 장소에서. 줄 바꿈과 패딩도 여기에 추가됩니다. 이것은 각 줄의 후행 공백과 수동으로 추가 해야하는 첫 번째 줄의 선행 공백을 제외한 모든 패딩을 처리합니다. (다음 줄의 선행 공백은 일치하는 문자열에서 나옵니다).


1

, 12 바이트

FN«→↗⌈X²⊖ι‖M

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

 N              Input as a number
F «             Loop over implicit range
   →            Move right (because mirroring moves the cursor)
         ι      Current index
        ⊖       Decremented
      X²        Power of 2
     ⌈          Ceiling
    ↗           Draw diagonal line
          ‖M    Mirror image

선 길이는 1, 1, 2, 4, 8 ... 2 ^ (N-2)이므로 어색한 계산입니다.



0

배치, 218 바이트

@echo off
set/a"n=1<<%1"
set s=set t=
%s%/\
set l=for /l %%i in (2,1,%n%)do call
%l% %s% %%t%% 
%l%:l
:l
echo %t%
set/an-=1,m=n^&n-1
%s%%t: /=/ %
%s%%t:\ = \%
if %m% neq 0 exit/b
%s%%t:/ =/\%
%s%%t: \=/\%

참고 : 6 행은 공백으로 끝납니다. 끝에서 2n 인 행을 제외하고 매번 가지를 왼쪽과 오른쪽으로 적절하게 이동하면 가지가 대신 분기됩니다.


0

Haxe, 181 바이트

function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");

또는 일부 선택적 공백이있는 경우 :

function g(n):String
  return
    (n -= 2) == -1
    ? "/\\"
    : [ for (y in 0...1 << n)
        [ for (x in 0...4 << n)
          x + y + 1 == 2 << n
          ? "/"
          : x - y == 2 << n
            ? "\\"
            : " "
        ].join("")
      ].concat([ for (y in g(n + 1).split("\n"))
        y + y
      ]).join("\n");

나는 적당한 크기의 공간 문자 배열을 먼저 만든 다음 포크 경로를 반복적으로 낮추고 (각 반복마다 더 밀도가 높은) 솔루션을 잠시 연구하고있었습니다. 그러나 230 바이트 이상 유지되었습니다. 이 접근 방식은 @Laikoni의 Haskell 접근 방식과 거의 같습니다. :StringHaxe는 반환 유형이 항상 문자열임을 식별하기에 충분히 똑똑하지 않기 때문에를 가지고 있지 않아도 벗어날 수 없었습니다 .

이것은 함수일 뿐이며 테스트 할 전체 프로그램은 다음과 같습니다.

class Main {
    public static function main(){
        function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");
        Sys.println(g(Std.parseInt(Sys.args()[0])));
    }
}

에서 위를 넣고 Main.hx함께 컴파일 haxe -main Main.hx -neko frac.n및 테스트합니다 neko frac.n 4(대체 4원하는 순서로).


0

PHP, 188 바이트

온라인 버전

function f($l,$r=0,$m=1){global$a;for(;$i<$l;$i++)$i<$l/2?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m):f($l/2^0,$r+$l/2,2*$m);}f(2**$argv[1]/2);echo join("\n",$a);

넓히는

function f($l,$r=0,$m=1){
global$a;    
for(;$i<$l;$i++)    
$i<$l/2
    ?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m)
    :f($l/2^0,$r+$l/2,2*$m);
}
f(2**$argv[1]/2);
echo join("\n",$a);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.