ASCIIボクセルを印刷する


28

で構成されるキューブを表すバイナリ値の配列を読み取るプログラムを作成するn×n×nn×n×nn3個の小さいキューブます。各値は、指定された位置にボクセル(小さな立方体)が存在するかどうかを示します。プログラムは、指定された配列をASCIIグラフィックとして出力する必要があります(つまり、コンソールからの出力またはファイルへの書き込みを意味します)。

次の2×2×2配列を考えてみましょう。

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

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

この場合、出力は次のようになります(ここでは、垂直方向のスペースが少ないコードエディタ/コンソールでの表示ほど良くありません)。

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

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

12×12×12入力文字列の例はこちら(ペーストビン)にあります。7×7×7入力文字列の新しい例はこちらにあります。

ASCIIの仕様

ボクセルの各コーナーは、+それにつながるエッジがある限り、aで表されます。+複数の単位長さで直線エッジがある場合にも描かれています。エッジには次の3つのタイプがあります:左から右----への水平、前/から後への水平、および垂直

|
|

それらのそれぞれは、+(長く見える限り)で終わる必要があります。エッジは、1つの平面を2つ以上の部分に分割した場合には描画されません(+上記のエッジに関連する場合とは異なります)。他の人の後ろに隠れている構造は描かれてはいけません。

「描画」は基本的に平行投影なので、上面、右側面、前面のみが表示されます-常に同じ角度から。

詳細

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

10

  • 1次元:最上位から最下位までレイヤーごと
  • 2次元:1行ずつ後ろ(最も遠い)から前(最も近い)まで
  • 3番目の次元:各行の左から右へのボクセル

コンソールを使用するか、ファイルを入出力として読み込むかはユーザー次第です。コード/アプローチ方法を教えてください

審査

これはcodegolfなので、バイト数が最も少なくなります。これには、実際に作業を行う部分のみが含まれます-バイトをカウントするとき、入力が既に解析され変数に保存されているとみなすことができ、出力文字列を変数に保存して印刷する必要があります。解析と出力自体はカウントされません。

(そして、私は創造的な例で提出を支持します=)

これは、ロブのパズルページに触発されました。

回答:


12

Python(444361354バイト)

編集:非常に特殊なケースでコーナークロスを省略する別のバグを見つけました。単純な修正によりコードに50バイトが追加されたので、もう少し詳しく調べてみました。これでバグが修正され、83バイトも短くなりました。非常にハックになりつつあります。また、5つのforループを削除したかったのですが、まだ解決策が見つかりませんでした。何か案は?

編集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」に1つの「+」が多すぎるようです。(私が投稿した7x7x7の1つを試すこともできますか?)
flawr 14

@flawr:そのプラス記号はfar 4(右下隅)に属しているため、正しいはずです。:) 7x7x7ケースを追加します。誰もがそれを投稿するとこのページが乱雑になると思ったので、私は最初にそれを省きましたが、私はそれでいいと思います。
エミール14

ああ、そうですね。大きな縦方向のスペースにだまされていたと思います。
flawr

20

Lua(1442バイト)

ボーナスアニメーション!:)
例と同じ形式のクールなボクセルアートがある場合は、コメントにリンクして、
それからアニメーションを作成します 7x7x7
ボーナスアニメーション
12x12x12
ボーナス2
これは私の最初のコードゴルフであるため、非常に面倒で改善する予定ですそれまたは別の言語への移植。
ここに私が持っているものがありますが、現在はわずかにゴルフの2.5kB以下です(この時点でインデントの空白を削除しました、私は後で続きます)

これは、約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

編集:アニメーションを作成するための編集を含む、オリジナル(3kB以上)のバージョンはありません(自分で実行してアニメーションが必要な場合は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の例からの出力はここにあります

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

ちょうどそう非luanersは)=あなたの結果を再現できること-うわー、それはカウントされませんが、あなたはまた、解析/出力コードを含めることができます)偉大=を探します
flawr

新しい例も含めましたが、それも含めていただければ幸いです=)
flawr 14

新しい7x7x7サンプルで更新され、pastebin文字列からテーブルを生成するためのスニペットも追加されました。
PiGuy

@ 7x7x7:プログラムが凹面の垂直エッジを描画しないようです。上のレイヤーの背面(さらに)側の曲線の上部のように。または同様に、最下層の前面(近く)右側に。私はアニメーションが大好きです!
flawr

@flawrありがとう、それを修正し、バイトカウントを減らすのに少し時間を費やし、現在は1.5kB未満になりました。また、アニメーションの作成に使用した完全なコードを追加しました。
PiGuy 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.