Imprimir Voxels ASCII

28

Escriba un programa que lea una matriz de valores binarios n×n×n que represente un cubo n×n×n , que consta de n3 cubos más pequeños. Cada valor dice si hay un voxel (cubo pequeño) presente en la posición dada o no. El programa debe generar la matriz dada como un gráfico ASCII (eso significa salida a través de la consola o escribir en un archivo).

Ejemplos

Consideremos las siguientes matrices 2×2×2 :

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

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

En este caso, la salida debería verse así (no se ve tan bien aquí como en editores de código / consolas con menos espacio vertical):

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

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

12×12×127×7×7

Especificaciones de la ASCII

Cada esquina de un vóxel está representada por un +mientras exista algún borde que lo lleve. También +se dibujan cuando hay un borde recto que tiene más de una unidad de largo. Hay tres tipos de aristas: la horizontal de izquierda a derecha ----, la horizontal de atrás hacia adelante /y la vertical

|
|

Cada uno de esos tiene que terminar en un +(siempre visible). Los bordes no se dibujarán cuando subdividan un plano plano en dos o más piezas (a diferencia de lo que se +refiere a los bordes como se indicó anteriormente). Las estructuras que están ocultas detrás de otros no deben dibujarse.

El 'dibujo' es básicamente una proyección paralela, por lo que solo son visibles los lados superior, derecho y frontal, siempre desde el mismo ángulo.

Detalles

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

10

  • 1a dimensión: capa por capa desde la parte superior a la inferior
  • 2da dimensión: fila por fila atrás (más alejado) al frente (más cercano)
  • 3a dimensión: vóxeles en cada fila de izquierda a derecha

Si usa la consola o lee archivos como entrada y salida, depende de usted. Por favor , cuéntenos sobre su código / cómo se acercó a ella.

Juzgar

Este es codegolf, por lo que gana la menor cantidad de bytes. Esto incluye SOLO la parte que realmente hace el trabajo: al contar bytes, puede considerar la entrada ya analizada y guardada en una variable y debe tener la cadena de salida guardada en una variable, lista para imprimir. El análisis y la salida en sí no cuentan.

(Y votaré las presentaciones con ejemplos creativos =)

Esto fue inspirado por la página de Rob's Puzzle .

falla
fuente

Respuestas:

12

Python ( 444 361 354 bytes)

Editar: Encontré otro error que omitiría un cruce de esquina en casos muy especiales. Una solución directa agregó 50 bytes al código, así que intenté descifrarlo un poco más. Ahora el error está solucionado e incluso es 83 bytes más corto. Se está volviendo muy hacky. También quería deshacerme del ciclo de cinco veces para pero todavía no pude encontrar una solución. ¿Algunas ideas?

Edición 2: con una importación muy larga puedo guardar otros 7 caracteres.

Ni muy corto ni muy elegante, pero nuevamente es un problema complejo:

#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

Primero dibuja todos los vóxeles individuales con todas las líneas una encima de la otra. Luego genera solo los caracteres superiores y elimina esas líneas y cruces en planos planos que no deben dibujarse de acuerdo con las especificaciones.

Supongo que es posible jugar golf un poco más, pero 444 es un número tan bueno. :)

Ejemplo de salida 3x3x3 y 7x7x7 (con algunas líneas nuevas eliminadas):

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

                +----+----+----+    +----+----+----+           
               /              /|   /              /|           
              +    +----+    + |  +    +----+    + |           
             /    /|   /    /  + /    /|   /    /  +           
            +    + |  +    +  / +    + |  +    +  /            
           /    /  +-/    /  + /    /  +-/    /  +             
          +----+  /-+----+  /-+----+  /-+----+  /--+           
          |    | +  |    | +  |    | +  |    | +  /|           
        +----+ | |+----+ | |+----+ | |+----+ | | + |           
       /    /| + /    /| + /    /| + /    /| + |/  +           
      +    + | |+    + | |+    + | |+    + | | +   |           
     /    /  + /    /  + /    /  + /    /  + |   + |           
    +    +----+    +   |+    +----+    +   | +  /| +           
   /              /  + /              /  + | | + | |           
  +----+----+----+  /|+----+----+----+  /| + |/--+ |           
  |              | + ||              | + | |-+  /  +           
  |              |/--+|              |/--+ |   +  /            
  +----+----+----+  / +----+----+----+  /  +  /  +             
    +    +  / +    +--- +    +  /-+    +  /--+  /--+           
   /    /  + /              /  + /    /  +   | +  /|           
  +----+  / +----+----+----+  /-+----+  /--+ |/  + |           
  |    | +  |              | +  |    | +  /|-+  /  +           
  |    | |-+|              |/  +|    | | + |   +  /            
  +    + |  +----+----+----+  /|+    + |/  +  /  +             
  |    | +----+----+ | |+    + ||    | +  /--+  /              
  |    |/         /| + /    /  +|    |   +   | +               
  +    +----+----+ | |+----+  /-+    +  /--+ |/                
  |              | + ||    | +  |    | +  /|-+                 
  |              | | +|    | | +|    |/  + |                   
  +----+----+    + | |+    + |/|+----+  /  +                   
    +    +--|    | + ||    | + |  +    +  /                    
   /        |    | |-+|    |   +-/    /  +                     
  +----+----+    + |  +    +  / +----+  /                      
  |              | +  |    | +  |    | +                       
  |              |/   |    |/   |    |/                        
  +----+----+----+    +----+    +----+                         
Emil
fuente
1
¡Buen trabajo! Muy compacto en comparación con mi desorden. ¡Comprueba tus bordes cóncavos! (faltan signos más) - repl.it/XA9/2
PiGuy
@PiGuy: ¡Buena captura! Creo que lo arreglé. Hizo que mi código fuera un poco más largo, pero también encontré algunas cosas más relacionadas con el golf, por lo que mágicamente sigo teniendo el mismo número de bytes.
Emil
Parece que hay un '+' demasiado en el '4' más cercano. (¿Puedes probar el 7x7x7 que
publiqué
@flawr: Ese signo más pertenece al extremo 4 (esquina inferior derecha), por lo que debe ser correcto. :) Agregaré el caso 7x7x7. Primero lo dejé fuera porque pensé que desordenaría esta página si todos la publican, pero supongo que está bien.
Emil
Ah, ahora veo, creo que me engañaron los grandes espacios verticales.
flawr
20

Lua (1442 bytes)

¡Animaciones extra! :)
Si tiene algún arte voxel genial en el mismo formato que los ejemplos, enlácelo en los comentarios y haré una animación con él
7x7x7
Animación extra
12x12x12
Bono 2
Este es mi primer código de golf, por lo que es bastante desordenado y planeo mejorar o portándolo a un idioma diferente.
Esto es lo que tengo, en este momento a poco menos de 2.5kB apenas golfizado (solo eliminé el espacio en blanco de sangría en este punto, continuaré más adelante)

Aquí está la versión ahora ~ 1.4kB de golf y minificada (tenga en cuenta que la tabla "a" en la primera línea es el marcador de posición para la matriz de vóxeles):

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

Editar : Aquí está la versión original (más de 3kB) sin golf, incluidas mis ediciones para hacer la animación (si la está ejecutando usted mismo y desea la animación, cambie falsela parte inferior del código a 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])

Aquí hay una muestra de código que llenará la matriz de vóxel de una cadena para una matriz de vóxel de 3x3x3. (Tomará cualquier cadena en un formato similar, pero asegúrese de que sea un cubo o que las cosas probablemente se rompan).
Para usar esto, inserte este fragmento justo después de la primera línealocal 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

Aquí está la salida del patrón de vóxel 12x12x12 dado : (y sí, se ve mejor en una consola normal / aparato de visualización de texto, hay un poco de espacio vertical demasiado aquí)

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

Aquí está la salida del ejemplo 7x7x7 aquí

              +----+----+----+    +----+----+----+
             /              /|   /              /|
            +    +----+    + |  +    +----+    + |
           /    /|   /    /  + /    /|   /    /  +
          +    + |  +    +  / +    + |  +    +  / 
         /    /  +-/    /  + /    /  +-/    /  +  
        +----+  /-+----+  /-+----+  /-+----+  /--+
        |    | +  |    | +  |    | +  |    | +  /|
      +----+ | |+----+ | |+----+ | |+----+ | | + |
     /    /| + /    /| + /    /| + /    /| + |/  +
    +    + | |+    + | |+    + | |+    + | | +   |
   /    /  + /    /  + /    /  + /    /  + |   + |
  +    +----+    +   |+    +----+    +   | +  /| +
 /              /  + /              /  + | | + | |
+----+----+----+  /|+----+----+----+  /| + |/--+ |
|              | + ||              | + | |-+  /  +
|              |/--+|              |/--+ |   +  / 
+----+----+----+  / +----+----+----+  /  +  /  +  
  +    +  / +    +----+    +  /-+    +  /--+  /--+
 /    /  + /              /  + /    /  +   | +  /|
+----+  / +----+----+----+  /-+----+  /--+ |/  + |
|    | +  |              | +  |    | +  /|-+  /  +
|    | |-+|              |/  +|    | | + |   +  / 
+    + |  +----+----+----+  /|+    + |/  +  /  +  
|    | +----+----+ | |+    + ||    | +  /--+  /   
|    |/         /| + /    /  +|    |   +   | +    
+    +----+----+ | |+----+  /-+    +  /--+ |/     
|              | + ||    | +  |    | +  /|-+      
|              | | +|    | | +|    |/  + |        
+----+----+    + | |+    + |/|+----+  /  +        
  +    +--|    | + ||    | + |  +    +  /         
 /        |    | |-+|    |   +-/    /  +          
+----+----+    + |  +    +  / +----+  /           
|              | +  |    | +  |    | +            
|              |/   |    |/   |    |/             
+----+----+----+    +----+    +----+              
PiGuy
fuente
Wow, se ve genial =) ¿Podría incluir también el código de análisis / salida a pesar de que no cuenta, solo para que los que no sean usuarios puedan reproducir sus resultados =)
error
Incluí
Actualizado con la nueva muestra de 7x7x7, también se agregó el fragmento para generar la tabla a partir de las cadenas de pastebin.
PiGuy
@ 7x7x7: Parece que su programa no dibuja bordes verticales cóncavos. Como en la parte superior de esa curva en el lado posterior (más) de la capa superior. o de manera similar en el lado derecho frontal (cercano) en la capa más baja. ¡Me encantan las animaciones!
flawr
@flawr Gracias, lo arreglé y pasé algún tiempo haciendo que el byte contara hacia atrás y ahora estoy por debajo de 1.5kB, y también agregué el código completo que utilicé para crear las animaciones.
PiGuy