3D ASCII Block Building


82

Tantangan

Tulis sebuah program yang mengambil array bilangan bulat 11x11, dan buat sebuah bangunan blok ASCII 3D, di mana setiap nilai dalam array mewakili ketinggian kolom blok pada koordinat yang sesuai dengan posisi array. Tinggi negatif adalah kolom "mengambang" - hanya blok atas yang terlihat.

Contoh

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

Memasukkan

Input akan menjadi daftar 121 bilangan bulat, baik dibaca dari stdin (pilihan pemisah terserah Anda), atau diteruskan sebagai array (bisa 1D atau 2D).

Ketinggian akan berada di kisaran -11 hingga 11.

Keluaran

Bangunan yang dihasilkan dapat ditulis ke stdout, ditampilkan langsung di layar, atau dikembalikan sebagai string yang dipisahkan baris baru.

Ruang putih terkemuka dan tertinggal diizinkan.

Peraturan Bangunan

Bentuk blok 3D individual terlihat seperti ini:

 ___
/\__\
\/__/

Dan kubus blok 2x2x2 terlihat seperti ini:

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

Ketika blok tumpang tindih, blok yang lebih tinggi diutamakan daripada yang lebih rendah, blok di depan diutamakan di belakang, dan blok di sebelah kiri diutamakan daripada yang di sebelah kanan. Satu-satunya kasus khusus adalah bahwa baris paling atas dari sebuah blok tidak boleh menimpa karakter non-spasi di belakangnya.

Interpretasi ketinggian kolom dapat dijelaskan dengan melihat representasi 2D dari samping.

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

Uji Kasus

Jika Anda ingin mencoba solusi Anda pada beberapa input lagi, saya telah mengumpulkan beberapa test case di sini .

Kemenangan

Ini adalah , sehingga pengiriman terpendek (dalam byte) menang.


9
Ohh boy, bersiaplah untuk solusi 300+ byte. Tantangan bagus. +1
totallyhuman

7
@totallyhuman Nah, Dennis akan memiliki solusi 9-byte untuk ini dalam 20 menit.
Diakon

3
Apakah perspektif harus seperti yang ditunjukkan dengan bagian kiri bawah data input di latar depan? Fakta bahwa ini bukan elemen data pertama atau terakhir membuatnya lebih sulit. Apakah dapat diterima untuk 1. menjaga pemetaan apa adanya dan menggambar output dengan kolom kanan bawah di latar depan atau 2. menggambar gambar cermin atau 90 derajat rotasi data? Salah satu dari ini akan membuat elemen data terakhir sesuai dengan kolom di latar depan, yang akan lebih mudah.
Level River St

3
Saya merasa cenderung menggunakan mesin game nyata (atau sebagian darinya) untuk membuat foto dan mengubahnya menjadi ASCII
Stan Strum

@LevelRiverSt Itu sepertinya permintaan yang masuk akal - Anda dapat memilih urutan 121 elemen masukan untuk menjadi apa pun yang paling masuk akal untuk solusi Anda, selama pemesanan Anda konsisten. Harus dimungkinkan untuk menghasilkan setiap jenis tata letak yang dapat diproduksi dengan urutan default.
James Holderness

Jawaban:


25

Arang , 70 69 68 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔E¹¹⮌I⪪S,θ

Baca array, pisahkan setiap baris pada koma dan dilemparkan ke integer, tetapi juga balikkan setiap baris, karena kami ingin menggambar kanan-ke-kiri sehingga kolom kiri menimpa kolom kanan. (Dimensi lain sudah memiliki perilaku menimpa yang diinginkan.)

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

Loop melalui i) garis dan badan atas k) tinggi l) baris m) kolom. (Looping melalui baris teratas pertama dan kemudian badan menghindari menimpa tubuh dengan baris atas.)

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

Lompat ke posisi kubus.

≔§§θλμη

Ambil ketinggian di baris dan kolom saat ini.

¿∨⁼±η⊕κ‹κη

Uji apakah sebuah kubus harus digambar pada ketinggian ini untuk baris dan kolom ini.

¿ι“↗⊟&⁹κUhnI”___

Gambarlah tubuh atau bagian atas kubus.


Ketika saya mengubah yang pertama 3ke 33, saya hanya mendapatkan 11 blok di menara. Secara umum menara tampaknya ditutup pada jam 11. Bagaimana hal itu terjadi?
Fabian Röling

@Fabian Saya agak bingung F¹¹F¹¹F¹¹itu bukan petunjuk ...
Neil

Saya tidak tahu bahasa pemrograman ini, saya hanya bermain-main sedikit dengan tautan TIO.
Fabian Röling

30

C,  376   350   313   309  285 byte

Terima kasih kepada @Jonathan Frech karena telah menghemat empat 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);}

Cobalah online!

Belum dibuka:

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

Tidak 26*66bisa 1716?
Jonathan Frech

@ JonathanFrech Tentu, saya lupa tentang itu.
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(...)(dengan asumsi btidak bergantung pada e, yang saya pikir tidak).
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`
`)

Disimpan 26 byte dari saran @ Neil .

Tidak disatukan

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,...'___'))))),tampaknya menghemat 26 byte.
Neil

@Neil Brilliant! Menggambar semua baris teratas pertama menyelamatkan saya kesulitan memeriksa non-spasi.
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)

Cobalah online!

Terjemahan Python dari pendekatan Neil's Charcoal.


Senang melihat solusi Python golf untuk ini. Proof-of-concept Python saya lebih dari 900 byte!
James Holderness

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

5

APL (Dyalog Unicode) , 117 116 112 byte SBCS

a23 550⋄{i11 0+⍵+.×3 23-7897⊤⍨65⋄(,2 5ia)←745366⊤⍨104⋄(3i1⌽¯1a)⌈←1j[⍋-/↑j←⍸↑⎕↑¨⊂⌽1,11/2]⋄' _/\'[a]

Cobalah online!


5

Tcl, 380 409 byte

Sergiol pengguna telah sibuk menyelesaikan ini dengan sangat baik:

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

Cobalah online!

Konten Asli

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

Cobalah online!

Sayangnya, ini adalah apa adanya. Itu hanya sedikit lebih mudah di mata ketika "tidak diserang"

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

Membangun string, sesuai persyaratan. Mengambil array dari stdin. Pergi dari bawah ke atas, depan ke belakang, kanan ke kiri pada data string. Lakukan dalam dua lintasan, satu kali untuk tepi atas dan lagi untuk sisa tubuh masing-masing kubus.

Saya mencoba membuatnya lebih kecil menggunakan beberapa lambda mojo fungsional yang manis, tetapi sayangnya, itu membuatnya lebih besar.


Anda dapat bermain golf: tio.run/…
sergiol

Lebih banyak bermain golf: tio.run/…
sergiol

Lebih lanjut: tio.run/…
sergiol

Namun lebih lanjut: tio.run/…
sergiol

Lebih banyak lagi: tio.run/##lVHtboJAEPx/…
sergiol
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.