3D ASCII 블록 빌딩


82

도전

11x11 정수 배열을 취하고 3D ASCII 블록 빌딩을 구성하는 프로그램을 작성하십시오. 여기서 배열의 각 값은 배열 위치와 일치하는 좌표에서 블록 열의 높이를 나타냅니다. 음수 높이는 "부동"열이며 상단 블록 만 표시됩니다.

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /\__\          /\/\__\__\__\__\__\__\
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /\/__/         /\/\/__/__/__/__/__/__/
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /\/\__\        /\/\/\__\      /\/\/__/
 1, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,    \/\/\__\      /\/\/\/__/     /\/\/__/
 0, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,     \/\/__/     /\/\/\/\__\    /\/\/__/
 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,      \/\__\    /\/\/\/\/__/   /\/\/__/
 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,       \/__/    \/\/\/\/\__\_  \/\/__/
 1, 0, 0, 4, 3, 2, 1, 0, 0, 0, 1,                 \/\/\/\/__/_\_ \/__/
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,            ___   \/\/\/__/__/_\_         ___
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,           /\__\   \/\/__/__/__/_\       /\__\
 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

입력

입력은 121 개의 정수 목록으로, stdin에서 읽거나 (분리자를 선택하는 것은 사용자에게 달려 있음) 배열로 전달됩니다 (1D 또는 2D 일 수 있음).

높이는 -11에서 11 사이입니다.

산출

생성 된 건물은 stdout에 작성되거나 화면에 직접 표시되거나 줄 바꿈으로 구분 된 문자열로 반환 될 수 있습니다.

선행 및 후행 공백이 허용됩니다.

건축 규칙

개별 3D 블록의 모양은 다음과 같습니다.

 ___
/\__\
\/__/

그리고 2x2x2 블록의 큐브는 다음과 같습니다 :

  ______
 /\__\__\
/\/\__\__\
\/\/__/__/
 \/__/__/

블록이 겹치면 높은 블록이 낮은 블록보다 우선하고, 앞에있는 블록은 그 뒤로 이동하고 왼쪽의 블록은 오른쪽의 블록보다 우선합니다. 유일한 특별한 경우는 블록의 맨 위 줄이 공백이 아닌 문자를 덮어 쓰지 않아야한다는 것입니다.

열 높이의 해석은 측면에서 2D 표현을 보면 가장 잘 설명 할 수 있습니다.

HEIGHT:  1    2    3   -3   -2   -1
                  __   __
             __  |__| |__|  __
        __  |__| |__|      |__|  __
       |__| |__| |__|           |__|

테스트 사례

몇 가지 추가 입력으로 솔루션을 시험 해보고 싶다면 여기 몇 가지 테스트 사례를 정리했습니다 .

승리

이것은 이므로 가장 짧은 제출 (바이트)이 이깁니다.


9
오 소년, 300 바이트 이상의 솔루션을 준비하십시오. 좋은 도전입니다. +1
완전 인간

7
@totallyhuman Nah, Dennis는 20 분 안에 9 바이트 솔루션을 제공 할 것입니다.
Deacon

3
입력 데이터의 왼쪽 아래에 전경이 표시되어야합니까? 이것이 데이터의 첫 번째 또는 마지막 요소가 아니라는 사실은 그것을 어렵게 만듭니다. 1. 매핑을 그대로 유지하고 전경의 오른쪽 아래 열로 출력을 그리거나 2. 미러 이미지 또는 데이터의 90도 회전을 그릴 수 있습니까? 이 중 하나가 마지막 데이터 요소를 포 그라운드의 열과 일치하게하므로 더 쉽습니다.
레벨 리버 St

3
실제 게임 엔진 (또는 그 일부)을 사용하여 사진을 렌더링하고 ASCII로 변환하는 경향이 있습니다.
Stan Strum

@LevelRiverSt 합리적인 요청처럼 보입니다. 주문이 일관된 한 121 개의 입력 요소 순서를 솔루션에 가장 적합한 것으로 선택할 수 있습니다. 기본 순서로 생성 할 수있는 모든 종류의 레이아웃을 생성 할 수 있어야합니다.
James Holderness

답변:


25

, 70 69 68 바이트

≔E¹¹⮌I⪪S,θF²F¹¹F¹¹F¹¹«J⁻⁻⁺λκ×μ³ι⁻λκ≔§§θλμη¿∨⁼±η⊕κ‹κη¿ι“↗⊟&⁹κUhnI”___

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

≔E¹¹⮌I⪪S,θ

왼쪽 열이 오른쪽 열을 덮어 쓰도록 오른쪽에서 왼쪽으로 그리려면 배열을 읽고 쉼표로 각 줄을 나누고 정수로 캐스트하고 각 줄을 반대로 바꿉니다. (다른 차원은 이미 덮어 쓰기 동작을 원했습니다.)

F²F¹¹F¹¹F¹¹«

i) 상단 라인과 바디 k) 높이 l) 행 m) 열을 반복합니다. 첫 번째 맨 위 줄을 반복 한 다음 본문은 맨 위 줄로 본문을 덮어 쓰지 않습니다.

J⁻⁻⁺λκ×μ³ι⁻λκ

큐브의 위치로 이동하십시오.

≔§§θλμη

현재 행과 열에서 높이를 가져옵니다.

¿∨⁼±η⊕κ‹κη

이 행과 열에 대해이 높이에서 큐브를 그릴 지 여부를 테스트하십시오.

¿ι“↗⊟&⁹κUhnI”___

입방체의 몸통 또는 상단을 그립니다.


첫 번째 3를로 변경 33하면 타워에 11 블록 만 있습니다. 일반적으로 타워는 11 일로 제한되어있는 것 같습니다. 어떻게됩니까?
Fabian Röling

@ Fabian 나는 F¹¹F¹¹F¹¹단서가 아닌 약간 혼란 스럽습니다 ...
Neil

나는이 프로그래밍 언어를 모른다. 나는 단지 TIO 링크로 조금 놀았다.
Fabian Röling

30

C,  376   350   313   309  285 바이트

4 바이트를 절약 한 @Jonathan Frech에게 감사합니다!

#define F for(
char*t,G[26][67],*s;i,j,e,k,v,x,y;b(){F s="\\/__//\\__\\ ___ ";*s;--y,s+=5)F e=5;e--;*t=*s<33&*t>32?*t:s[e])t=G[y]+x+e;}f(int*M){F;e<1716;++e)G[e/66][e%66]=32;F k=0;++k<12;)F i=0;i<11;++i)F j=11;j--;v+k||b())x=i+j*3+k,y=14+i-k,(v=M[i*11+j])>=k&&b();F;++e<26;)puts(G+e);}

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

풀림 :

#define F for(

char *t, G[26][67], *s;
i, j, e, k, v, x, y;

b()
{
    F s="\\/__//\\__\\ ___ "; *s; --y, s+=5)
        F e=5; e--; *t=*s<33&*t>32?*t:s[e])
            t = G[y]+x+e;
}

f(int*M)
{
    F; e<1716; ++e)
        G[e/66][e%66] = 32;

    F k=0; ++k<12;)
        F i=0; i<11; ++i)
            F j=11; j--; v+k||b())
                x = i+j*3+k,
                y = 14+i-k,
                (v=M[i*11+j])>=k && b();

    F; ++e<26;)
        puts(G+e);
}

26*661716없습니까?
Jonathan Frech

@JonathanFrech 물론, 나는 그것을 잊었다.
Steadybox

*s==32-> *s<33.
Jonathan Frech

for(e=k=1;e;++k)for(e=-> for(k=1;e;++k)for(e=.
Jonathan Frech

#define B b(...)&++e-> #define B++e&b(...)(에 b의존하지 않는다고 가정 e합니다.
Jonathan Frech

9

자바 스크립트 (ES6), 277 251 바이트

a=>(n=55,$=f=>[...Array(n)].map((_,i)=>f(i)),S=$(_=>$(_=>' ')),n=11,$(l=>$(z=>$(y=>$(x=>(x=10-x,X=x*3+y+z,Y=y-z+n,Z=a[y][x])<=z&&Z+z+1?0:l?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),S.map(r=>r.join``).join`
`)

@Neil의 제안 에서 26 바이트를 절약했습니다 .

언 골프

a=>(
    n=55,
    $=f=>[...Array(n)].map((_,i)=>f(i)),
    S=$(_=>$(_=>' ')),
    n=11,
    $(l=>
        $(z=>$(y=>$(x=>(
            x=10-x,
            X=x*3+y+z,
            Y=y-z+n,
            Z=a[y][x],
            Z<=z && Z+z+1 || (
                l
                ? ['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s))
                : S[Y].splice(X+1,3,...'___')
            )
        ))))
    ),
    S.map(r=>r.join``).join`\n`
)

2
,$(w=>$(z=>$(y=>$(x=>(Z=a[y][x=10-x,X=x*3+y+z,Y=y-z+n,x])<=z&&Z+z+1?0:w?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),26 바이트를 절약하는 것 같습니다.
Neil

@ 닐 브릴리언트! 모든 상단 라인을 먼저 그리면 공백이 아닌 것을 확인하는 데 어려움이 없습니다.
darrylyeo

6

파이썬 2 , 243 바이트

a=input()
s=eval(`[[' ']*55]*23`)
for h in range(7986):
 k=h%3;x=h/3%11;y=h/33%11;z=h/363%11;i=h/3993;u=y+z-x*3+30;v=y-z+10
 if~-(z>=a[y][10-x]!=~z):
	if i*k:s[v+k][u:u+5]='\//\____/\\'[k%2::2]
	if~-i:s[v][u+1+k]='_'
for l in s:print''.join(l)

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

닐의 숯 접근 방식의 파이썬 번역.


이를위한 골프 파이썬 솔루션을 만나서 반갑습니다. 내 파이썬 개념 증명은 900 바이트 이상이었습니다!
James Holderness

3
+1+k-> -~k.
Jonathan Frech


5

Tcl, 380 409 바이트

사용자 sergiol 은 이것을 매우 훌륭하게 처리하는 데 바빴습니다.

set X [read stdin]
proc L {a b c d e s} {time {incr z
set y -1
time {incr y
set x -1
time {if {abs([set Z [lindex $::X [expr ($y+1)*11-[incr x]-1]]])==$z|$z<$Z} {set s [string repl [string repl $s [set i [expr -3*$x+57*$y-55*abs($z)+701]] $i+$b $a] [incr i $c] $i+$e $d]}} 11} 11} 12
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

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

원본 내용

set xs [read stdin]
proc L {a b c d e s} {set z 0
while {[incr z]<12} {set y -1
while {[incr y]<11} {set x -1
while {[incr x]<11} {set Z [lindex $::xs [expr ($y+1)*11-$x-1]]
if {abs($Z)==$z||$z<$Z} {set i [expr -3*$x+57*$y-55*abs($z)+701]
set s [string repl [string repl $s $i $i+$b $a] [incr i $c] $i+$e $d]}}}}
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

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

아아, 그것이 무엇인가. “무진장”일 때 눈에 조금 더 쉬울뿐입니다.

set s [string repeat [string repeat " " 55]\n 23]

proc loops {s0 i0 io s1 i1} {
  set z  0; while {[incr z] < 12} {
  set y -1; while {[incr y] < 11} {
  set x -1; while {[incr x] < 11} {
    set Z [lindex $::xs [expr {($y+1) * 11 - $x - 1}]]
    if {abs($Z) == $z || $z < $Z} {
        set i [expr {-3*$x + 57*$y - 55*abs($z) + 701}]
        set ::s [string replace $::s $i $i+$i0 $s0]
        incr i $io
        set ::s [string replace $::s $i $i+$i1 $s1]
    }
  } } }
}

loops ""      -1 -55 \
       ___     2
loops /\\__\\  4  56 \
      \\/__/   4

puts $s

요구 사항에 따라 문자열을 작성합니다. stdin에서 배열을 가져옵니다. 문자열 데이터를 위에서 아래로, 앞뒤로, 오른쪽에서 왼쪽으로 이동합니다. 상단 모서리에 대해 한 번, 각 큐브의 나머지 본문에 대해 두 번의 패스로 수행합니다.

나는 달콤한 기능성 람다 모조를 사용하여 더 작게 만들려고했지만 아아, 그것을 더 크게 만들었습니다.


당신은 골프 수 있습니다 : tio.run/…
sergiol

더 많은 골프 : tio.run/…
sergiol


그러나 더 : tio.run/...
sergiol

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