Drukuj woksele ASCII

28

Napisanie programu, który odczytuje n×n×n tablicę wartości binarnych, które reprezentują takie n×n×n modułu, który składa się z n3 mniejszych modułów. Każda wartość określa, czy woksel (mały sześcian) jest obecny w danej pozycji, czy nie. Program musi wypisać podaną tablicę jako grafikę ASCII (co oznacza wyjście przez konsolę lub zapis do pliku).

Przykłady

Rozważmy następujące tablice 2×2×2 :

[
 [[0,0],
  [1,0]]
 [[1,1],
  [1,0]],
]

[
 [[0,0],
  [0,0]]
 [[1,1],
  [1,1]],
]

W takim przypadku wynik powinien wyglądać tak (tutaj nie wygląda tak dobrze, jak w edytorach kodu / konsolach z mniejszą przestrzenią pionową):

  +----+
 /    /|-+----+
+----+ |     /|
|    | +----+ |
|    | |    | +
+    + |    |/
|    | +----+
|    |/
+----+

    +----+----+
   /         /|
  +         + |
 /         /  +
+----+----+  /
|         | +
|         |/
+----+----+

12×12×127×7×7

Specyfikacje ASCII

Każdy róg woksela jest reprezentowany przez +dowolną krawędź prowadzącą do niego. +Są sporządzone, gdy jest liniał, który jest więcej niż jedną jednostkę długości. Istnieją trzy rodzaje krawędzi: poziomy od lewej do prawej ----, poziomy od tyłu do przodu /i pionowy

|
|

Każdy z nich musi kończyć się na +(tak długo widoczny). Krawędzie nie zostaną narysowane, jeśli podzielą jedną płaską płaszczyznę na dwie lub więcej części (inaczej niż +w stosunku do krawędzi, jak podano powyżej). Struktury ukryte za innymi nie mogą być rysowane.

„Rysunek” jest w zasadzie rzutem równoległym, więc widoczne są tylko górna, prawa i przednia strona - zawsze pod tym samym kątem.

Detale

n=1,2,,1212×12×123×3×3

10

  • 1. wymiar: warstwa po warstwie, od najwyższego do najniższego
  • 2. wymiar: rząd za rzędem od tyłu (najdalej) do przodu (najbliżej)
  • Trzeci wymiar: woksele w każdym rzędzie od lewej do prawej

Niezależnie od tego, czy korzystasz z konsoli, czy odczytujesz pliki jako dane wejściowe i wyjściowe, zależy od Ciebie. Proszę nam opowiedzieć o kodzie / jak się zbliżał.

Osądzać

To jest kodegolf, więc wygrywa najmniejsza liczba bajtów. Obejmuje to TYLKO tę część, która faktycznie działa - podczas zliczania bajtów można uznać dane wejściowe za już przeanalizowane i zapisane w zmiennej oraz trzeba zapisać ciąg wyjściowy w zmiennej, gotowy do wydrukowania. Analiza i samo wyjście nie jest brane pod uwagę.

(I będę głosować za przesłaniem kreatywnych przykładów =)

To było zainspirowane stroną Puzzle Roba .

wada
źródło

Odpowiedzi:

12

Python ( 444 361 354 bajtów)

Edycja: Znalazłem inny błąd, który pomijałby narożnik w bardzo szczególnych przypadkach. Prosta poprawka dodała 50 bajtów do kodu, więc spróbowałem trochę pograć w golfa. Teraz błąd został naprawiony i jest nawet o 83 bajty krótszy. Robi się bardzo hack. Chciałem też pozbyć się pięciokrotnej pętli for, ale nie mogłem jeszcze znaleźć rozwiązania. Jakieś pomysły?

Edycja 2: Przy bardzo długim imporcie mogę zapisać kolejne 7 znaków.

Ani bardzo krótki, ani bardzo elegancki, ale z drugiej strony jest to złożony problem:

#input:
u=[[[1,1,1],[1,0,1],[1,1,1]],
   [[1,0,1],[0,0,0],[1,0,1]],
   [[1,1,1],[1,0,1],[1,1,1]]]

#actual code that counts:
r=range
n=len(u)
g=r(n)
a=([' ']*9*n+['\n'])*6*n
t='/|-+\n '
d=dict(zip(t+'%!=*',2*t))
for y,z,x,i,j in __import__('itertools').product(g,g,g[::-1],r(6),r(8)):
 if abs(i+j-6)<5*u[x][y][z]:a[(9*n+1)*(i+3*x+2*y)+j+5*z-2*y+2*n]+='./    %|+====* ||    ! *|    !/.*----+'[8*i+j-8]
o=''.join((d[x[-1]],' ')[x[-2:]in('%/','!|','=-')or x[-4:]=='*++*']for x in a)

#output:
print o

Najpierw rysuje wszystkie poszczególne woksele ze wszystkimi liniami jedna na drugiej. Następnie wypisuje tylko najwyższe postacie i pozbywa się tych linii i krzyży na płaszczyznach płaskich, których nie należy rysować zgodnie ze specyfikacją.

Myślę, że można trochę pograć w golfa, ale 444 to całkiem niezła liczba. :)

Przykład danych wyjściowych 3x3x3 i 7x7x7 (z usuniętymi niektórymi znakami nowej linii):

        +----+----+----+   
       /              /|   
      +    +----+    + |   
     /    /|   /    /  +   
    +    +----+    +   |   
   /              /  + |   
  +----+----+----+  /| +   
  |              | + | |   
  |              | |-+ |   
  +    +----+    + |/  +   
  |    | +--|    | +  /    
  |    |/   |    |   +     
  +    +----+    +  /      
  |              | +       
  |              |/        
  +----+----+----+         

                +----+----+----+    +----+----+----+           
               /              /|   /              /|           
              +    +----+    + |  +    +----+    + |           
             /    /|   /    /  + /    /|   /    /  +           
            +    + |  +    +  / +    + |  +    +  /            
           /    /  +-/    /  + /    /  +-/    /  +             
          +----+  /-+----+  /-+----+  /-+----+  /--+           
          |    | +  |    | +  |    | +  |    | +  /|           
        +----+ | |+----+ | |+----+ | |+----+ | | + |           
       /    /| + /    /| + /    /| + /    /| + |/  +           
      +    + | |+    + | |+    + | |+    + | | +   |           
     /    /  + /    /  + /    /  + /    /  + |   + |           
    +    +----+    +   |+    +----+    +   | +  /| +           
   /              /  + /              /  + | | + | |           
  +----+----+----+  /|+----+----+----+  /| + |/--+ |           
  |              | + ||              | + | |-+  /  +           
  |              |/--+|              |/--+ |   +  /            
  +----+----+----+  / +----+----+----+  /  +  /  +             
    +    +  / +    +--- +    +  /-+    +  /--+  /--+           
   /    /  + /              /  + /    /  +   | +  /|           
  +----+  / +----+----+----+  /-+----+  /--+ |/  + |           
  |    | +  |              | +  |    | +  /|-+  /  +           
  |    | |-+|              |/  +|    | | + |   +  /            
  +    + |  +----+----+----+  /|+    + |/  +  /  +             
  |    | +----+----+ | |+    + ||    | +  /--+  /              
  |    |/         /| + /    /  +|    |   +   | +               
  +    +----+----+ | |+----+  /-+    +  /--+ |/                
  |              | + ||    | +  |    | +  /|-+                 
  |              | | +|    | | +|    |/  + |                   
  +----+----+    + | |+    + |/|+----+  /  +                   
    +    +--|    | + ||    | + |  +    +  /                    
   /        |    | |-+|    |   +-/    /  +                     
  +----+----+    + |  +    +  / +----+  /                      
  |              | +  |    | +  |    | +                       
  |              |/   |    |/   |    |/                        
  +----+----+----+    +----+    +----+                         
Emil
źródło
1
Dobra robota! Bardzo kompaktowy w porównaniu do mojego bałaganu. Sprawdź jednak swoje wklęsłe krawędzie! (brak znaków plus) - repl.it/XA9/2
PiGuy
@PiGuy: Good catch! Myślę, że to naprawiłem. To spowodowało, że mój kod był trochę dłuższy, ale znalazłem też trochę golfa, więc magicznie wciąż jestem przy tej samej liczbie bajtów.
Emil
Wydaje się, że jest jeden „+” za dużo na „4”. (Czy możesz też wypróbować 7x7x7, które opublikowałem?)
flawr
@flawr: Ten znak plus należy do dalekiego 4 (prawy dolny prawy róg), więc powinien być odpowiedni. :) Dodam skrzynkę 7x7x7. Najpierw go pominąłem, ponieważ myślałem, że gdyby strona została opublikowana, zagraciłaby tę stronę, ale myślę, że to w porządku.
Emil,
Ach, teraz widzę - myślę, że oszukały mnie duże pionowe przestrzenie.
flawr
20

Lua (1442 bajty)

Animacje bonusowe! :)
Jeśli masz jakąś fajną grafikę wokselową w tym samym formacie co przykłady, połącz ją w komentarzach, a zrobię z niej
animację
Animacja bonusowa
7x7x7 12x12x12
Premia 2
To jest mój pierwszy golfowy kod, więc jest dość niechlujny i planuję ulepszyć lub przeniesienie go na inny język.
Oto, co mam, w tej chwili przy prawie 2,5kB prawie nie grałem (właśnie usunąłem białe wcięcia w tym miejscu, będę kontynuować później)

Oto gra w golfa w wersji ~ 1,4 kB i zminiaturyzowana (zwróć uwagę, że tabela „a” w pierwszym wierszu jest symbolem zastępczym macierzy wokseli):

local a={}
local b,c=table,string;local d,e,f,g,h,i=b.concat,#a,c.gsub,c.gmatch,ipairs,b.insert;local function j(k,l,m)return a[k]and a[k][l]and a[k][l][m]==1 end;local n={}for o=1,e*5+1 do n[o]={}for p=1,e*7+1 do n[o][p]=" "end end;local q=[[
__6hhhh7
_g    ij
1aaaa2 j
b    d 5
b    de_
3cccc4__
]]local function r(k,l,m)local s=q;if j(k,l,m)then local t,u,v,w,x,y,z,A=j(k-1,l,m),j(k+1,l,m),j(k,l,m-1),j(k,l,m+1),j(k,l-1,m),j(k+1,l+1,m),j(k+1,l,m+1)," "if t then s=f(s,"[ai]"," ")end;if u and not y then A=A.."c"end;if u and not z then A=A.."e"end;if v then A=A.."bg"end;if w then A=A.."di"end;if x then if not j(k,l-1,m+1)then A=A.."j"end;A=A.."h"end;if t then if w and j(k-1,l,m+1)then A=A.."2"end;if v and j(k-1,l,m-1)then A=A.."1"end end;if u then if w and j(k+1,l,m+1)then A=A.."4"end;if v and j(k+1,l,m-1)then A=A.."3"end end;if x then if w and j(k,l-1,m+1)then A=A.."7"end;if v and j(k,l-1,m-1)then A=A.."6"end;if u and j(k+1,l-1,m)then A=A.."5"end end;s=f(f(f(f(f(s,"["..A.."]"," "),"[ach]","-"),"[bdj]","|"),"[gie]","/"),"[1234567]","+")else s=nil end;return s end;local B,C;local D=e*2-1;local E=1;for k=e,1,-1 do for l=1,e do for m=1,e do B=(l-1)*-2+(m-1)*5+D;C=(l-1)*2+(k-1)*3+E;local s=r(k,l,m)if s then local F={}for G in s:gmatch("[^\n]+")do local H={}for I in G:gmatch(".")do i(H,I)end;i(F,H)end;for J,K in h(F)do for L,I in h(K)do if I~="_"then n[C+J-1][B+L-1]=I end end end end end end end;for o,a in h(n)do print(d(a))end

Edycja : Oto oryginalna (ponad 3kB) wersja bez golfa, w tym moje zmiany do tworzenia animacji (jeśli uruchamiasz ją samodzielnie i chcesz animację, zmień falsena dole kodu na true.

local v = {}
local depth = #v;

function voxel(y,z,x)
  return (v[y] and v[y][z] and v[y][z][x]==1)
end

local canvas = {}
print("Constructing canvas of depth",depth)
for i=1,depth*5+1 do
  canvas[i] = {}
  for j=1,depth*7+1 do
    canvas[i][j] = " "
  end
end

local voxelProto = [[
__6hhhh7
_g    ij
1aaaa2 j
b    d 5
b    de_
3cccc4__
]]

function renderVoxel(y,z,x)
  local vox = voxelProto
  if (voxel(y,z,x)) then
    local up = voxel(y-1,z,x)
    local down = voxel(y+1,z,x)
    local left = voxel(y,z,x-1)
    local right = voxel(y,z,x+1)
    local back = voxel(y,z-1,x)
    local downFront = voxel(y+1,z+1,x)
    local downRight = voxel(y+1,z,x+1)

    if (up) then
      vox = vox:gsub("[ai]"," ")
    end
    if (down and not downFront) then
      vox = vox:gsub("[c]"," ")
    end
    if (down and not downRight) then
      vox = vox:gsub("[e]"," ")
    end
    if (left) then
      vox = vox:gsub("[bg]"," ")
    end
    if (right) then
      vox = vox:gsub("[di]"," ")
    end
    if (back and not voxel(y,z-1,x+1)) then
      vox = vox:gsub("[j]"," ")
    end
    if (back or up) then
      vox = vox:gsub("[h]"," ")
    end
    if (up and right and voxel(y-1,z,x+1)) then
      vox = vox:gsub("[2]"," ")
    end
    if (up and left and voxel(y-1,z,x-1)) then
      vox = vox:gsub("[1]"," ")
    end
    if (down and right and voxel(y+1,z,x+1)) then
      vox = vox:gsub("[4]"," ")
    end
    if (down and left and voxel(y+1,z,x-1)) then
      vox = vox:gsub("[3]"," ")
    end
    if (back and right and voxel(y,z-1,x+1)) then
      vox = vox:gsub("[7]"," ")
    end
    if (back and left and voxel(y,z-1,x-1)) then
      vox = vox:gsub("[6]"," ")
    end
    if (back and down and voxel(y+1,z-1,x)) then
      vox = vox:gsub("[5]"," ")
    end

    vox = vox:gsub("[ach]","-")
    vox = vox:gsub("[bdj]","|")
    vox = vox:gsub("[gie]","/")
    vox = vox:gsub("[1234567]","+")
  else
    vox = nil
  end
  return vox
end
local xpos,ypos
local minx = depth*2-1
local miny = 1;

local pic = {}
function drawCanvas()
  for k,v in pairs(canvas) do
    pic[k] = table.concat(v)
  end
  return table.concat(pic,"\n")
end

local timeline = {}
print("Compositing voxels")
for y=depth,1,-1 do
  for z=1,depth do
    for x = 1,depth do
      xpos = (z-1)*-2 + (x-1)*5 + minx
      ypos = (z-1)*2 + (y-1)*3 + miny
      local vox = renderVoxel(y,z,x)
      if (vox) then
        local vt = {}
        for line in vox:gmatch("[^\n]+") do
          local vtl = {}
          for c in line:gmatch(".") do
            table.insert(vtl,c)
          end
         table.insert(vt,vtl)
        end
        for ly,chars in ipairs(vt) do
          for lx,c in ipairs(chars) do
            if (c ~= "_") then
              canvas[ypos+ly-1][xpos+lx-1] = c
            end
          end
        end
        table.insert(timeline,drawCanvas())
      end
    end
  end
end

if (false) then -- change to true if you want to see the animation!
  for i=1,#timeline do
    local t = os.clock() + 0.05
    io.write(timeline[i],'\n\n')
    io.flush()
    while (t > os.clock()) do end
  end
end         
print(timeline[#timeline])

Oto próbka kodu, który zapełni macierz wokseli z ciągu znaków macierzy wokseli 3x3x3. (Zajmie każdy ciąg w podobnym formacie, ale upewnij się, że jest to sześcian, bo inaczej prawdopodobnie się zepsuje.)
Aby użyć tego, wstaw tę porcję bezpośrednio po pierwszym wierszulocal v = {}

local vs = [[
100
000
000

110
100
000

111
110
101
]]
for layer in vs:gmatch("[^a]+") do
 local a = {}
 for row in layer:gmatch("[^\n]+") do
 local b = {}
 for _vox in row:gmatch("[01]") do
 table.insert(b,(_vox=="1") and 1 or 0)
 end
 table.insert(a,b)
 end
 table.insert(v,a)
end

Oto dane wyjściowe z podanego wzorca wokseli 12 x 12 x 12 : (i tak, wygląda to lepiej na zwykłym urządzeniu do przeglądania konsoli / tekstu, tutaj jest trochę za dużo pionowych odstępów)

                                                                          +----+----+
                                                                         /         /|
                                                                        +----+----+ |
                                                                        |         | +
                                                            +----+      |         |/
                                                           /    /|      +    +----+
                                                          +----+ |      |    | +----+
                                                          |    | +      |    |/    /|
                                                          |    | |      +    +----+ |
                                                          +    + |      |         | +
              +----+----+                         +----+--|    | +      |         |/
             /         /|                        /        |    | |      +    +----+
            +----+----+ |                       +----+----+    + |      |    | +----+
            |         | +                       |              | +      |    |/    /|
            |         |/       +----+----+----+ |              | |      +    +----+ |
            +    +----+       /              /| +    +----+    + |      |         | +
            |    | +         +----+----+----+ | |    | +--|    | +      |         |/
            |    | |         |              | + |    |/   |    | |      +----+----+
            +    + |         |              | | +    +----+    + |            
            |    | +         +    +----+    + | |              | +            
            |    | |         |    | +--|    | + |              |/             
            +    + |         |    |/   |    | | +----+----+----+              
            |    | +----+    +    +----+    + |                               
            |    |/    /|    |              | +                               
            +    +----+ |    |              |/                                
            |         | +    +----+----+----+                                 
            |         |/                                                      
            +----+----+                                       +----+----+     
                                                             /         /|     
                                                  +----+    +----+----+ |     
                                                 /    /|    |         | +     
                                                +----+ |    |         |/      
                                                |    | +    +    +----+       
      +----+----+----+  +----+----+----+----+---|    | |---+|    | +----+-+----+----+
     /              /| /                        +    + |    |    |/    /|          /|
    +----+----+----+ |+                         |    | +    +    +----+ |         + |
    |              | +                          |    | |    |         | +        /  +
    |              | |      +----+----+----+    +    + |    |         |/        +  /
    +    +----+    + |     /              /|    |    | +    +    +----+        /  +
    |    | +--|    | +    +----+----+----+ |    |    | |    |    | +          +  /
    |    |/   |    | |    |              | +    +    + |    |    | |         /  +
    +    +----+    + |    |              | |    |    | +    +    + |        +  /
    |              | +    +    +----+    + |    |    | |    |    | +       /  +
    |              | |    |    | +--|    | +    +    + |    |    |/       +  /
    +----+----+    + |    |    |/   |    | |    |    | +    +----+       /  + 
      +----+--|    | +    +    +----+    + |    |    |/                 +  /  
     /        |    | |    |              | +    +----+                 /  +   
    +----+----+    + |    |              |/                           +  /    
    |              | +    +----+----+----+                           /  +     
    |              |/                                               +  /      
    +----+----+----+                                               /  +       
      +                                                           +  /        
     /                                                           /  +         
    +                                                           +  /          
   /                                                           /  +           
  +                                                           +  /            
 /                                                           /  +             
+----+----+----+----+----+----+----+----+----+----+----+----+  /              
|                                                           | +               
|                                                           |/                
+----+----+----+----+----+----+----+----+----+----+----+----+   

Oto wynik z przykładu 7x7x7 tutaj

              +----+----+----+    +----+----+----+
             /              /|   /              /|
            +    +----+    + |  +    +----+    + |
           /    /|   /    /  + /    /|   /    /  +
          +    + |  +    +  / +    + |  +    +  / 
         /    /  +-/    /  + /    /  +-/    /  +  
        +----+  /-+----+  /-+----+  /-+----+  /--+
        |    | +  |    | +  |    | +  |    | +  /|
      +----+ | |+----+ | |+----+ | |+----+ | | + |
     /    /| + /    /| + /    /| + /    /| + |/  +
    +    + | |+    + | |+    + | |+    + | | +   |
   /    /  + /    /  + /    /  + /    /  + |   + |
  +    +----+    +   |+    +----+    +   | +  /| +
 /              /  + /              /  + | | + | |
+----+----+----+  /|+----+----+----+  /| + |/--+ |
|              | + ||              | + | |-+  /  +
|              |/--+|              |/--+ |   +  / 
+----+----+----+  / +----+----+----+  /  +  /  +  
  +    +  / +    +----+    +  /-+    +  /--+  /--+
 /    /  + /              /  + /    /  +   | +  /|
+----+  / +----+----+----+  /-+----+  /--+ |/  + |
|    | +  |              | +  |    | +  /|-+  /  +
|    | |-+|              |/  +|    | | + |   +  / 
+    + |  +----+----+----+  /|+    + |/  +  /  +  
|    | +----+----+ | |+    + ||    | +  /--+  /   
|    |/         /| + /    /  +|    |   +   | +    
+    +----+----+ | |+----+  /-+    +  /--+ |/     
|              | + ||    | +  |    | +  /|-+      
|              | | +|    | | +|    |/  + |        
+----+----+    + | |+    + |/|+----+  /  +        
  +    +--|    | + ||    | + |  +    +  /         
 /        |    | |-+|    |   +-/    /  +          
+----+----+    + |  +    +  / +----+  /           
|              | +  |    | +  |    | +            
|              |/   |    |/   |    |/             
+----+----+----+    +----+    +----+              
PiGuy
źródło
Wow, wygląda świetnie =) Czy możesz również dołączyć parsowanie / kod wyjściowy, nawet jeśli się nie liczy - tylko po to, żeby nie-luanersi mogli odtworzyć twoje wyniki =)
flawr 17'14
Podałem
Zaktualizowany o nową próbkę 7x7x7, dodano także fragment kodu do generowania tabeli z ciągów pastebin.
PiGuy
@ 7x7x7: Wygląda na to, że twój program nie rysuje wklęsłych pionowych krawędzi. Jak na górze tej krzywej na tylnej (dalszej) stronie górnej warstwy. lub podobnie z przodu (blisko) prawej strony na najniższej warstwie. Całkowicie uwielbiam animacje!
flawr
@flawr Dzięki, naprawiłem to, a także poświęciłem trochę czasu na odliczanie bajtu i jestem teraz poniżej 1,5 kB, a także dodałem pełny kod, którego użyłem do tworzenia animacji.
PiGuy,