Tòa nhà khối 3D ASCII


82

Thử thách

Viết chương trình lấy một mảng số nguyên 11x11 và xây dựng khối xây dựng khối 3D ASCII, trong đó mỗi giá trị trong mảng biểu thị chiều cao của một cột khối tại tọa độ khớp với vị trí mảng. Chiều cao âm là cột "nổi" - chỉ có thể nhìn thấy khối trên cùng.

Thí dụ

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 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,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

Đầu vào

Đầu vào sẽ là một danh sách gồm 121 số nguyên, được đọc từ stdin (lựa chọn dấu phân tách tùy thuộc vào bạn) hoặc được truyền vào dưới dạng một mảng (có thể là 1D hoặc 2D).

Độ cao sẽ nằm trong phạm vi -11 đến 11.

Đầu ra

Tòa nhà được tạo có thể được ghi vào thiết bị xuất chuẩn, hiển thị trực tiếp trên màn hình hoặc được trả về dưới dạng chuỗi phân tách dòng mới.

Khoảng trắng hàng đầu và dấu được cho phép.

Quy tắc xây dựng

Hình dạng của một khối 3D riêng lẻ trông như thế này:

 ___
/\__\
\/__/

Và một khối lập phương 2x2x2 trông như thế này:

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

Khi các khối chồng lên nhau, một khối cao hơn được ưu tiên hơn một khối thấp hơn, các khối ở phía trước được ưu tiên hơn các khối phía sau và các khối ở bên trái được ưu tiên hơn các khối bên phải. Trường hợp đặc biệt duy nhất là dòng trên cùng của một khối không bao giờ ghi đè lên bất kỳ ký tự không phải không gian nào phía sau nó.

Việc giải thích chiều cao cột có thể được giải thích tốt nhất bằng cách nhìn vào biểu diễn 2D từ bên cạnh.

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

Các trường hợp thử nghiệm

Nếu bạn muốn thử giải pháp của mình trên một vài đầu vào nữa, tôi đã kết hợp một vài trường hợp thử nghiệm ở đây .

Chiến thắng

Đây là , vì vậy bài nộp ngắn nhất (tính bằng byte) sẽ thắng.


9
Ohh boy, sẵn sàng cho hơn 300 giải pháp byte. Thử thách tốt. +1
hoàn toàn là

7
@totallyhuman Nah, Dennis sẽ có một giải pháp 9 byte cho việc này trong 20 phút.
Phó tế

3
Có phối cảnh phải được hiển thị với phía dưới bên trái của dữ liệu đầu vào ở phía trước không? Thực tế rằng đây không phải là yếu tố đầu tiên hoặc cuối cùng của dữ liệu làm cho nó khó khăn hơn. Có thể chấp nhận được 1. giữ nguyên ánh xạ và vẽ đầu ra với cột dưới cùng bên phải ở phía trước hoặc 2. vẽ hình ảnh phản chiếu hoặc xoay 90 độ của dữ liệu? Một trong hai điều này sẽ làm cho phần tử dữ liệu cuối cùng tương ứng với cột ở nền trước, sẽ dễ dàng hơn.
Cấp sông St

3
Tôi cảm thấy có xu hướng sử dụng một công cụ trò chơi thực sự (hoặc một phần của nó) để kết xuất một bức ảnh và chuyển đổi nó thành ASCII
Stan Strum

@LevelRiverSt Điều đó có vẻ như là một yêu cầu hợp lý - bạn có thể chọn thứ tự của 121 yếu tố đầu vào là bất cứ điều gì có ý nghĩa nhất cho giải pháp của bạn, miễn là đơn hàng của bạn phù hợp. Nó phải có thể tạo ra mọi loại bố cục có thể được sản xuất với thứ tự mặc định.
James Holdiness

Câu trả lời:


25

Than , 70 69 68 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

≔E¹¹⮌I⪪S,θ

Đọc mảng, chia từng dòng trên dấu phẩy và chuyển thành số nguyên, nhưng cũng đảo ngược từng dòng, vì chúng ta muốn vẽ từ phải sang trái để các cột bên trái ghi đè lên các cột bên phải. (Các kích thước khác đã có hành vi ghi đè mong muốn.)

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

Vòng lặp qua i) các dòng trên cùng và các thân k) chiều cao l) hàng m) cột. (Vòng qua các dòng trên cùng đầu tiên và sau đó các cơ quan tránh các phần ghi đè lên các dòng trên cùng.)

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

Nhảy đến vị trí của khối lập phương.

≔§§θλμη

Lấy chiều cao ở hàng và cột hiện tại.

¿∨⁼±η⊕κ‹κη

Kiểm tra xem một khối lập phương nên được vẽ ở độ cao này cho hàng và cột này.

¿ι“↗⊟&⁹κUhnI”___

Vẽ cơ thể hoặc đỉnh của khối lập phương.


Khi tôi thay đổi cái đầu tiên 3thành a 33, tôi chỉ nhận được 11 khối trong tháp. Trong các tòa tháp nói chung dường như được giới hạn ở mức 11. Điều đó xảy ra như thế nào?
Fabian Röling

@Fabian Tôi hơi bối rối đó F¹¹F¹¹F¹¹không phải là manh mối ...
Neil

Tôi không biết ngôn ngữ lập trình này, tôi chỉ chơi một chút với liên kết TIO.
Fabian Röling

30

C,  376   350   313   309  285 byte

Cảm ơn @Jonathan Frech đã lưu bốn byte!

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

Hãy thử trực tuyến!

Chưa được kiểm soát:

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

Không thể 26*66được 1716?
Jonathan Frech

@JonathanFrech Chắc chắn, tôi đã quên điều đó.
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(...)(giả sử bkhông phụ thuộc vào e, điều mà tôi nghĩ là không).
Jonathan Frech

9

JavaScript (ES6), 277 251 byte

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

Đã lưu 26 ​​byte từ đề xuất của @ Neil .

Bị đánh cắp

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,...'___'))))),dường như tiết kiệm 26 byte.
Neil

@Neil Rực rỡ! Vẽ tất cả các dòng trên cùng trước tiên giúp tôi tránh những rắc rối khi kiểm tra các khoảng không.
darrylyeo

6

Python 2 , 243 byte

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)

Hãy thử trực tuyến!

Một bản dịch Python của phương pháp tiếp cận than của Neil.


Rất vui khi thấy một giải pháp Python được đánh gôn cho việc này. Khái niệm bằng chứng Python của tôi là hơn 900 byte!
James Holdiness

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


5

Tcl, 380 409 byte

Người dùng sergiol đã rất bận rộn với việc này.

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]]]

Hãy thử trực tuyến!

Nội dung gốc

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]]]

Hãy thử trực tuyến!

Than ôi, nó là những gì nó được. Nó chỉ dễ nhìn hơn một chút khi mà

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

Xây dựng một chuỗi, theo yêu cầu. Lấy mảng từ stdin. Đi từ dưới lên trên, từ trước ra sau, từ phải sang trái qua dữ liệu chuỗi. Có phải trong hai lần vượt qua, một lần cho cạnh trên và một lần nữa cho phần còn lại của cơ thể của mỗi khối.

Tôi đã cố gắng làm cho nó nhỏ hơn bằng cách sử dụng một số mojo lambda chức năng ngọt ngào, nhưng than ôi, điều đó làm cho nó lớn hơn.


Bạn có thể chơi gôn: tio.run/ Kẻ
sergiol



Còn nữa: tio.run/ từ
sergiol

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.