3D ASCII Block Building


82

Wyzwanie

Napisz program, który pobiera tablicę liczb całkowitych 11 x 11 i konstruuje budowę bloku 3D ASCII, gdzie każda wartość w tablicy reprezentuje wysokość kolumny bloków o współrzędnych pasujących do pozycji tablicy. Wysokość ujemna to kolumna „pływająca” - widoczny jest tylko górny blok.

Przykład

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

Wejście

Wejście będzie listą 121 liczb całkowitych, odczytanych ze standardowego wejścia (wybór separatora zależy od Ciebie) lub przekazanych jako tablica (może być 1D lub 2D).

Wysokość będzie w zakresie od -11 do 11.

Wynik

Wygenerowany budynek można zapisać na standardowym ekranie, wyświetlić bezpośrednio na ekranie lub zwrócić jako ciąg oddzielony znakiem nowej linii.

Wiodące i końcowe białe znaki są dozwolone.

Zasady budowania

Kształt pojedynczego bloku 3D wygląda następująco:

 ___
/\__\
\/__/

A sześcian bloków 2x2x2 wygląda następująco:

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

Kiedy bloki zachodzą na siebie, wyższy blok ma pierwszeństwo przed dolnym, bloki z przodu mają pierwszeństwo przed tymi z tyłu, a bloki po lewej mają pierwszeństwo przed blokami po prawej. Jedynym szczególnym przypadkiem jest to, że górna linia bloku nigdy nie powinna zastępować znaków spacji za nim.

Interpretację wysokości kolumn można najlepiej wyjaśnić, patrząc z boku na dwuwymiarową reprezentację.

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

Przypadki testowe

Jeśli chcesz wypróbować swoje rozwiązanie na kilku większej liczby wejść, ja już ułożyła kilka przypadków testowych tutaj .

Zwycięski

To jest , więc wygrywa najkrótsze przesłanie (w bajtach).


9
Och, chłopcze, przygotuj się na ponad 300 bajtów. Dobre wyzwanie. +1
całkowicieludzki

7
@ totalniehuman Nah, Dennis będzie miał do tego 9-bajtowe rozwiązanie za 20 minut.
Diakon

3
Czy perspektywa musi być taka, jak pokazano z lewym dolnym rogu danych wejściowych na pierwszym planie? To, że nie jest to pierwszy ani ostatni element danych, utrudnia. Czy dopuszczalne jest 1. utrzymanie mapowania bez zmian i narysowanie danych wyjściowych z prawą dolną kolumną na pierwszym planie lub 2. narysowanie obrazu lustrzanego lub obrót danych o 90 stopni? Każdy z nich sprawiłby, że ostatni element danych odpowiadałby kolumnie na pierwszym planie, co byłoby łatwiejsze.
Level River St

3
Czuję się skłonni do korzystania z silnika prawdziwa gra (lub jego część) do renderowania zdjęcie i przekształcić ją w ASCII
Stan Strum

@LevelRiverSt Wydaje się, że jest to uzasadnione żądanie - możesz wybrać kolejność 121 elementów wejściowych tak, aby były najbardziej odpowiednie dla twojego rozwiązania, o ile zamówienie jest spójne. Musi istnieć możliwość wytworzenia każdego rodzaju układu, który można wytworzyć w domyślnej kolejności.
James Holderness

Odpowiedzi:


25

Węgiel drzewny , 70 69 68 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

≔E¹¹⮌I⪪S,θ

Przeczytaj tablicę, podziel każdą linię przecinkami i rzutuj na liczbę całkowitą, ale także odwróć każdą linię, ponieważ chcemy rysować od prawej do lewej, aby lewe kolumny nadpisały prawe kolumny. (Inne wymiary mają już pożądane zachowanie zastępowania).

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

Zapętlić i) górne linie i bryły k) wysokość l) rzędy m) kolumny. (Pętla przechodząca przez pierwsze górne linie, a następnie treści, pozwala uniknąć nadpisywania obiektów górnymi liniami.)

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

Skocz do pozycji sześcianu.

≔§§θλμη

Pobierz wysokość w bieżącym wierszu i kolumnie.

¿∨⁼±η⊕κ‹κη

Sprawdź, czy należy narysować sześcian na tej wysokości dla tego wiersza i kolumny.

¿ι“↗⊟&⁹κUhnI”___

Narysuj korpus lub górę sześcianu.


Kiedy zmieniam pierwszy 3na a 33, dostaję tylko 11 bloków w wieży. Ogólnie wieże wydają się być ograniczone do 11. Jak to się dzieje?
Fabian Röling

@Fabian Jestem trochę zdezorientowany, że F¹¹F¹¹F¹¹to nie był trop ...
Neil

Nie znam tego języka programowania, po prostu bawiłem się trochę z linkiem TIO.
Fabian Röling,

30

C,  376   350   313   309  285 bajtów

Dzięki @Jonathan Frech za uratowanie czterech bajtów!

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

Wypróbuj online!

Rozwinięty:

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

Może 26*66nie być 1716?
Jonathan Frech

@JathanathanFrech Jasne, zapomniałem o tym.
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(...)(zakładając, bże nie zależy e, co moim zdaniem nie zależy ).
Jonathan Frech

9

JavaScript (ES6), 277 251 bajtów

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

Zapisano 26 bajtów z sugestii @ Neila .

Nie golfił

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,...'___'))))),wydaje się oszczędzać 26 bajtów.
Neil

@Neil Brilliant! Narysowanie najpierw wszystkich górnych linii oszczędza mi trudu sprawdzania, czy nie ma spacji.
darrylyeo

6

Python 2 , 243 bajty

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)

Wypróbuj online!

Tłumaczenie Pythona podejścia Neila do Węgla drzewnego.


Miło jest zobaczyć w tym przypadku golfowe rozwiązanie Python. Mój proof-of-concept Pythona miał ponad 900 bajtów!
James Holderness

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


5

Tcl, 380 409 bajtów

Użytkownik sergiol był bardzo zajęty rozwiązywaniem tego problemu :

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

Wypróbuj online!

Oryginalna treść

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

Wypróbuj online!

Niestety, tak jest. To jest tylko odrobinę łatwiejsze dla oczu, gdy „nie golfia”

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

Buduje ciąg, zgodnie z wymaganiami. Pobiera tablicę ze standardowego wejścia. Przechodzi od dołu do góry, od przodu do tyłu, od prawej do lewej nad danymi ciągu. Robi to w dwóch przejściach, raz dla górnej krawędzi i ponownie dla reszty korpusu każdej kostki.

Próbowałem go zmniejszyć za pomocą jakiegoś słodkiego funkcjonalnego lambda mojo, ale, niestety, to go powiększyło.


Możesz grać w golfa: tio.run/…
sergiol

Więcej golfa: tio.run/...
sergiol


Jeszcze więcej: tio.run/…
sergiol

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.