Stampa ASCII Voxels


28

Scrivi un programma che legge una matrice n×n×n di valori binari che rappresentano un cubo n×n×n , che consiste di n3 cubi più piccoli. Ogni valore indica se è presente o meno un voxel (cubo piccolo) in una determinata posizione. Il programma deve generare l'array dato come un grafico ASCII (ciò significa output tramite console o scrittura su un file).

Esempi

Consideriamo i seguenti array 2×2×2 :

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

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

In questo caso l'output dovrebbe apparire così (qui non sembra buono come negli editor / console di codice con meno spazio verticale):

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

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

12×12×127×7×7

Specifiche dell'ASCII

Ogni angolo di un voxel è rappresentato da un +finché c'è un bordo che lo conduce. La +si ispirano anche quando v'è un bordo rettilineo che è più di un'unità. Esistono tre tipi di bordi: orizzontale da sinistra a destra ----, orizzontale da dietro a /verticale e verticale

|
|

Ognuno di questi deve finire in un +(per quanto visibile a lungo). I bordi non verranno disegnati quando suddividono un piano planare in due o più pezzi (diversamente dal +in relazione ai bordi come sopra indicato). Le strutture che sono nascoste dietro gli altri non devono essere disegnate.

Il "disegno" è fondamentalmente una proiezione parallela, quindi sono visibili solo i lati superiore, destro e anteriore, sempre dalla stessa angolazione.

Dettagli

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

10

  • 1a dimensione: strato per strato dal più alto al più basso
  • 2a dimensione: riga per riga indietro (più lontana) in avanti (più vicina)
  • 3a dimensione: voxel in ogni riga da sinistra a destra

Se usi la console o leggi i file come input e output dipende da te. Per favore, parlaci del tuo codice / di come ti sei avvicinato.

A giudicare

Questo è codegolf, quindi vince il minor numero di byte. Ciò include SOLO la parte che effettivamente funziona - quando si contano i byte è possibile considerare l'input già analizzato e salvato in una variabile e si deve salvare la stringa di output in una variabile, pronta per essere stampata. L'analisi e l'output stesso non contano.

(E valuterò le proposte con esempi creativi =)

Questo è stato ispirato dalla pagina Puzzle di Rob .

Risposte:


12

Python ( 444361 354 byte)

Modifica: ho trovato un altro bug che avrebbe omesso una croce d'angolo in casi molto speciali. Una correzione diretta ha aggiunto 50 byte al codice, quindi ho provato a spostarlo un po 'più in basso. Ora il bug è stato corretto ed è addirittura più breve di 83 byte. Sta diventando molto confuso. Volevo anche sbarazzarmi del cinque per ciclo ma non riuscivo ancora a trovare una soluzione. Qualche idea?

Modifica 2: Con un'importazione molto lunga posso salvare altri 7 caratteri.

Né molto corto né molto elegante, ma di nuovo è un problema complesso:

#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

Disegna innanzitutto tutti i singoli voxel con tutte le linee sovrapposte. Quindi emette solo i caratteri più in alto e si sbarazza di quelle linee e croci su piani planari che non dovrebbero essere disegnati secondo le specifiche.

Immagino sia possibile giocarci ancora un po ', ma 444 è un numero così bello. :)

Esempio di output 3x3x3 e 7x7x7 (con alcune nuove righe rimosse):

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

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

1
Bel lavoro! Molto compatto rispetto al mio pasticcio. Controlla i tuoi bordi concavi però! (segni più mancanti) - repl.it/XA9/2
PiGuy

@PiGuy: buona cattura! Penso di averlo corretto. Ha reso il mio codice un po 'più lungo ma ho anche trovato alcune cose oltre il golf, quindi sono magicamente ancora allo stesso numero di byte.
Emil,

Sembra che ci sia un '+' troppo sul '4' più vicino. (Puoi anche provare quello 7x7x7 che ho pubblicato?)
flawr

@flawr: quel segno più appartiene all'estremo 4 (angolo in basso a destra), quindi dovrebbe essere giusto. :) Aggiungerò il caso 7x7x7. L'ho lasciato fuori perché pensavo che avrebbe ingombrato questa pagina se tutti l'avessero postata, ma immagino che vada bene.
Emil,

Ah ora vedo - penso di essere stato ingannato dai grandi spazi verticali.
flawr

20

Lua (1442 byte)

Animazioni bonus! :)
Se hai delle fantastiche opere in voxel nello stesso formato degli esempi,
collegale nei commenti e ne realizzerò
Animazione bonus
un'animazione 7x7x7 12x12x12
Bonus 2
Questo è il mio primo codice golf, quindi è piuttosto disordinato e ho intenzione di migliorare o portandolo in un'altra lingua.
Ecco quello che ho, in questo momento a poco meno di 2,5 kB a mala pena golf (appena rimosso lo spazio di rientro a questo punto, continuerò più avanti)

Ecco la versione ora ~ 1.4kB golfizzata e minimizzata (nota che la tabella "a" sulla prima riga è il segnaposto per la matrice voxel):

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

Modifica : ecco la versione originale non salvata (oltre 3 KB), incluse le mie modifiche per realizzare l'animazione (se la stai eseguendo da solo e vuoi l'animazione, modifica la falseparte inferiore del codice in 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])

Ecco un esempio di codice che popolerà la matrice voxel da una stringa per una matrice voxel 3x3x3. (Ci vorrà qualsiasi stringa in un formato simile, ma assicurati che sia un cubo o che le cose probabilmente si rompano.)
Per usarlo, inserisci questo blocco subito dopo la prima rigalocal 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

Ecco l'output del dato modello voxel 12x12x12 : (e sì, sembra migliore su una normale console / apparato di visualizzazione del testo, qui c'è un po 'troppo spazio verticale)

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

Ecco l'output dell'esempio 7x7x7 qui

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

Caspita, sembra fantastico =) Potresti anche includere il codice di analisi / output anche se non conta - solo in modo che i non-luaner possano riprodurre i tuoi risultati =)
flawr

Ho incluso un nuovo esempio, sarebbe fantastico se si potesse includere anche quello =)
flawr

Aggiornato con il nuovo esempio 7x7x7, ha aggiunto anche lo snippet per generare la tabella dalle stringhe pastebin.
PiGuy,

@ 7x7x7: sembra che il tuo programma non disegna bordi verticali concavi. Come sopra quella curva sul lato posteriore (ulteriore) dello strato superiore. o similmente sul lato anteriore (vicino) a destra sul livello più basso. Adoro le animazioni!
flawr

@flawr Grazie, ho risolto il problema e ho trascorso un po 'di tempo a ridurre il conteggio dei byte e ora sono inferiore a 1,5 KB e ho aggiunto anche il codice completo che ho usato per creare le animazioni.
PiGuy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.