Друкуйте вокселі ASCII


28

Напишіть програму, яка зчитує n×n×n масив двійкових значень, що представляють n×n×n куб, який складається з n3 менших кубів. Кожне значення говорить про те, чи є в заданій позиції воксель (маленький кубик) чи ні. Програма повинна вивести заданий масив у вигляді графіки ASCII (це означає виведення через консоль або запис у файл).

Приклади

Розглянемо наступні масиви 2×2×2 :

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

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

У цьому випадку висновок повинен виглядати приблизно так (він виглядає не так добре, як у редакторах коду / консолях з меншим вертикальним простором):

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

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

12×12×127×7×7

Технічні характеристики ASCII

Кожен куточок вокселя представлений символом, до +якого є ребро, що веде до нього. +Також звертається , коли є прямий край , що більш ніж один блок довго. Існує три типи ребер: горизонтальний зліва направо ----, горизонтальний спина вперед /та вертикальний

|
|

Кожен з них повинен закінчуватися +(як довго видно). Краї не будуть намальовані, коли вони поділять одну площинну площину на дві або більше частин (на відміну +від ребер, як зазначено вище). Структури, які приховані за іншими, не можна малювати.

"Креслення" - це в основному паралельна проекція, тому видно лише верхню, праву і передню сторони - завжди з одного кута.

Деталі

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

10

  • 1-й вимір: шар за шаром від самого верхнього до нижнього
  • 2-й вимір: рядок за рядом назад (найдальше) спереду (найближчий)
  • 3-й вимір: вокселі в кожному рядку зліва направо

Чи будете ви використовувати консоль чи читати файли як вхідні та вихідні дані. Розкажіть, будь ласка , про свій код / ​​як ви зверталися до нього.

Судження

Це кодогольф, тому виграє найменша кількість байтів. Сюди входить ТОЛЬКО та частина, яка насправді виконує роботу - при підрахунку байтів ви можете вважати вхід вже розібраним і збереженим у змінній, і ви повинні мати рядок виводу, збережений у змінній, готовий до друку. Аналіз і сам вихід не враховуються.

(І я підтримаю публікації творчими прикладами =)

На це надихнула сторінка Робська головоломка .

Відповіді:


12

Python ( 444 361 354 байт)

Редагувати: Я знайшов ще одну помилку, яка опустила б кутовий хрест у дуже особливих випадках. Прямий виправлення вперед додало до коду 50 байт, тому я спробував трохи більше пробити його вниз. Тепер виправлено помилку і вона на 83 байти коротше. Це стає дуже хакітним. Я також хотів позбутися від п’ятірки для циклу, але не зміг знайти рішення. Якісь ідеї?

Редагувати 2: За допомогою дуже довгого імпорту я можу зберегти ще 7 символів.

Ні дуже короткий, ні дуже елегантний, але знову ж таки це складна проблема:

#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

Спочатку малює всі окремі вокселі всіма рядками один на одного. Потім він видає лише найвищих символів і позбавляється від тих ліній і хрестів на площинних площинах, які не повинні бути намальовані відповідно до специфікацій.

Я здогадуюсь, що можна в гольф це ще трохи, але 444 така гарна кількість. :)

Приклад 3x3x3 та 7x7x7 вихід (із видаленими новими рядками):

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

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

1
Хороша робота! Дуже компактний порівняно з моїм безладом. Перевірте свої увігнуті краї, хоча! (відсутні плюс знаки) - repl.it/XA9/2
PiGuy

@PiGuy: Добрий улов! Я думаю, що я це виправив. Це зробило мій код трохи довше, але я також знайшов деякі речі для гольфу далі, тож я магічно все ще знаходжуся на тому ж байті.
Еміль

Здається, є один "+" занадто багато на ближчому "4". (Чи можете ви також спробувати 7x7x7, який я опублікував?)
недолік

@flawr: Цей знак плюс належить до дальнього 4 (крайній нижній правий кут), тому він повинен бути правим. :) Я додам корпус 7x7x7. Я спершу її покинув, бо думав, що ця сторінка буде захаращена, якщо всі розмістять її, але я думаю, що це добре.
Еміль

А тепер я бачу - я думаю, що мене обдурили великі вертикальні простори.
недоторк

20

Луа (1442 байти)

Бонусні анімації! :)
Якщо у вас є якесь круте воксельне мистецтво в тому ж форматі, що і приклади, зв’яжіть його в коментарях, і я зроблю з нього анімацію
7x7x7
Бонусна анімація
12x12x12
Бонус 2
Це мій перший гольф-код, тому його досить безладно, і я планую вдосконалити це або переносять його на іншу мову.
Ось, що я маю, зараз трохи менше 2,5 КБ ледве гольфується (просто видалено пробіл пробілів у цій точці, я продовжуватиму пізніше)

Ось тепер ~ 1.4kB для гольфу та мінімізована версія (зверніть увагу, що таблиця "a" в першому рядку є заповнювачем матриці вокселів):

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

Редагувати : Ось оригінальна версія (понад 3 КБ) безгофрована версія, включаючи мої редагування для створення анімації (якщо ви запускаєте її самостійно та хочете анімацію, змініть falseнайближчу нижню частину коду на 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])

Ось зразок коду, який заповнить воксельну матрицю з рядка для 3x3x3 воксельної матриці. (Знадобиться будь-яка рядок у подібному форматі, але переконайтесь, що це куб, або речі, ймовірно, зламаються.)
Щоб скористатися цим, вставте цей фрагмент відразу після першого рядкаlocal 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

Ось вихід із заданого шаблону вокселів 12x12x12 : (і так, це краще виглядає на звичайному пристрої перегляду консолі / тексту, тут є занадто багато вертикального інтервалу)

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

Ось вихід із прикладу 7x7x7 тут

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

Нічого собі, виглядає чудово =) Чи можете ви також включити синтаксичний аналіз / вихідний код, хоча він не враховується - лише для того, щоб нелуанти могли відтворити ваші результати =)
flawr

Я включив новий приклад, було б чудово, якби ви могли також включити це =)
недолік

Оновлено новий зразок 7x7x7, також додано фрагмент для генерації таблиці з рядків пастбіну.
PiGuy

@ 7x7x7: Схоже, ваша програма не малює увігнутих вертикальних країв. Як на вершині цієї кривої на задній (подальшій) стороні верхнього шару. або аналогічно на передній (близькій) правій стороні нижнього шару. Я абсолютно люблю анімацію!
невдача

@flawr Спасибі, я виправив це, а також витратив деякий час на зменшення кількості байтів, і зараз я нижче 1,5 КБ, і я додав повний код, який я також використовував для створення анімації.
PiGuy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.