3D ASCIIブロックの構築


82

チャレンジ

整数の11x11配列を受け取り、3D ASCIIブロックビルディングを構築するプログラムを作成します。配列内の各値は、配列の位置に一致する座標のブロックの列の高さを表します。負の高さは「浮動」列です-一番上のブロックのみが表示されます。

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /\__\          /\/\__\__\__\__\__\__\
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /\/__/         /\/\/__/__/__/__/__/__/
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /\/\__\        /\/\/\__\      /\/\/__/
 1, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,    \/\/\__\      /\/\/\/__/     /\/\/__/
 0, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,     \/\/__/     /\/\/\/\__\    /\/\/__/
 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,      \/\__\    /\/\/\/\/__/   /\/\/__/
 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,       \/__/    \/\/\/\/\__\_  \/\/__/
 1, 0, 0, 4, 3, 2, 1, 0, 0, 0, 1,                 \/\/\/\/__/_\_ \/__/
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,            ___   \/\/\/__/__/_\_         ___
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,           /\__\   \/\/__/__/__/_\       /\__\
 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

入力

入力は121個の整数のリストで、stdinから読み取られるか(セパレーターの選択はユーザー次第)、配列として渡されます(1Dまたは2Dにすることができます)。

高さは-11〜11の範囲になります。

出力

生成された建物は、stdoutに書き込まれ、画面に直接表示されるか、改行で区切られた文字列として返されます。

先頭と末尾の空白は許可されます。

建築ルール

個々の3Dブロックの形状は次のようになります。

 ___
/\__\
\/__/

そして、ブロックの2x2x2キューブは次のようになります。

  ______
 /\__\__\
/\/\__\__\
\/\/__/__/
 \/__/__/

ブロックが重複する場合、高いブロックが低いブロックより優先され、前のブロックが後のブロックより優先され、左側のブロックが右側のブロックより優先されます。唯一の特殊なケースは、ブロックの一番上の行がその後ろのスペース以外の文字を上書きしないことです。

列の高さの解釈は、側面から2D表現を見ることで最もよく説明できます。

HEIGHT:  1    2    3   -3   -2   -1
                  __   __
             __  |__| |__|  __
        __  |__| |__|      |__|  __
       |__| |__| |__|           |__|

テストケース

さらにいくつかの入力でソリューションを試してみたい場合は、ここでいくつかのテストケースをまとめまし

勝ち

これはであるため、最短の送信(バイト単位)が優先されます。


9
ああ、300バイト以上のソリューションの準備をしてください。良い挑戦。+1
完全に人間的な

7
@totallyhumanああ、デニスはこれについて20分で9バイトのソリューションを用意する予定です。
執事

3
パースペクティブは、入力データの左下が前景に表示されている必要がありますか これがデータの最初または最後の要素ではないという事実は、それを難し​​くします。1.マッピングをそのままにして、右下の列を前景にして描画するか、2。鏡像を描画するか、データを90度回転させますか?これらのいずれかにより、最後のデータ要素がフォアグラウンドの列に対応するようになり、より簡単になります。
レベルリバーセント

3
私は写真をレンダリングし、ASCIIに変換するために、実際のゲームエンジン(またはその一部)を使用するように傾斜を感じる
スタン・ストラムを

@LevelRiverStそれは合理的な要求のように思えます-順序が一貫している限り、121個の入力要素の順序をソリューションにとって最も意味のあるものに選択できます。デフォルトの順序で作成できるあらゆる種類のレイアウトを作成できる必要があります。
ジェームズホルダーネス

回答:


25

70 69 68バイト

≔E¹¹⮌I⪪S,θF²F¹¹F¹¹F¹¹«J⁻⁻⁺λκ×μ³ι⁻λκ≔§§θλμη¿∨⁼±η⊕κ‹κη¿ι“↗⊟&⁹κUhnI”___

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔E¹¹⮌I⪪S,θ

配列を読み取り、各行をコンマで分割して整数にキャストしますが、右から左に描画して左の列が右の列を上書きするようにするため、各行を逆にします。(他の次元はすでに望ましい上書き動作をしています。)

F²F¹¹F¹¹F¹¹«

i)上の行と本文k)高さl)行m)列をループします。(最初の先頭行をループしてから本文をループすると、本文が先頭行で上書きされなくなります。)

J⁻⁻⁺λκ×μ³ι⁻λκ

キューブの位置にジャンプします。

≔§§θλμη

現在の行と列の高さを取得します。

¿∨⁼±η⊕κ‹κη

この行と列に対してこの高さで立方体を描画するかどうかをテストします。

¿ι“↗⊟&⁹κUhnI”___

本体または立方体の上部を描画します。


最初のもの3をに変更する33と、タワー内に11ブロックしかありません。一般的に、タワーは11で制限されているようです。
ファビアンレーリング

@ファビアン私はそれF¹¹F¹¹F¹¹が手がかりではなかったわずかに混乱しています...-
ニール

このプログラミング言語はわかりませんが、TIOリンクで少し遊んでみました。
ファビアンローリング

30

C、 376の   350   313   309  285バイト

4バイトを節約してくれた@Jonathan Frechに感謝します!

#define F for(
char*t,G[26][67],*s;i,j,e,k,v,x,y;b(){F s="\\/__//\\__\\ ___ ";*s;--y,s+=5)F e=5;e--;*t=*s<33&*t>32?*t:s[e])t=G[y]+x+e;}f(int*M){F;e<1716;++e)G[e/66][e%66]=32;F k=0;++k<12;)F i=0;i<11;++i)F j=11;j--;v+k||b())x=i+j*3+k,y=14+i-k,(v=M[i*11+j])>=k&&b();F;++e<26;)puts(G+e);}

オンラインでお試しください!

展開:

#define F for(

char *t, G[26][67], *s;
i, j, e, k, v, x, y;

b()
{
    F s="\\/__//\\__\\ ___ "; *s; --y, s+=5)
        F e=5; e--; *t=*s<33&*t>32?*t:s[e])
            t = G[y]+x+e;
}

f(int*M)
{
    F; e<1716; ++e)
        G[e/66][e%66] = 32;

    F k=0; ++k<12;)
        F i=0; i<11; ++i)
            F j=11; j--; v+k||b())
                x = i+j*3+k,
                y = 14+i-k,
                (v=M[i*11+j])>=k && b();

    F; ++e<26;)
        puts(G+e);
}

でき26*66ません1716か?
ジョナサンフレッチ

@JonathanFrech確かに、私はそれを忘れていました。
Steadybox

*s==32-> *s<33
ジョナサンフレッチ

for(e=k=1;e;++k)for(e=-> for(k=1;e;++k)for(e=
ジョナサンフレッチ

#define B b(...)&++e-> #define B++e&b(...)(仮定bはに依存しないeと思いますが、そうではないと思います)
ジョナサンフレッチ

9

JavaScript(ES6)、277 251バイト

a=>(n=55,$=f=>[...Array(n)].map((_,i)=>f(i)),S=$(_=>$(_=>' ')),n=11,$(l=>$(z=>$(y=>$(x=>(x=10-x,X=x*3+y+z,Y=y-z+n,Z=a[y][x])<=z&&Z+z+1?0:l?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),S.map(r=>r.join``).join`
`)

@Neil の提案から26バイトを節約しました

非ゴルフ

a=>(
    n=55,
    $=f=>[...Array(n)].map((_,i)=>f(i)),
    S=$(_=>$(_=>' ')),
    n=11,
    $(l=>
        $(z=>$(y=>$(x=>(
            x=10-x,
            X=x*3+y+z,
            Y=y-z+n,
            Z=a[y][x],
            Z<=z && Z+z+1 || (
                l
                ? ['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s))
                : S[Y].splice(X+1,3,...'___')
            )
        ))))
    ),
    S.map(r=>r.join``).join`\n`
)

2
,$(w=>$(z=>$(y=>$(x=>(Z=a[y][x=10-x,X=x*3+y+z,Y=y-z+n,x])<=z&&Z+z+1?0:w?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),26バイト節約できるようです。
ニール

@Neil Brilliant!すべての一番上の行を最初に描画すると、スペース以外をチェックする手間が省けます。
-darrylyeo

6

Python 2、243バイト

a=input()
s=eval(`[[' ']*55]*23`)
for h in range(7986):
 k=h%3;x=h/3%11;y=h/33%11;z=h/363%11;i=h/3993;u=y+z-x*3+30;v=y-z+10
 if~-(z>=a[y][10-x]!=~z):
	if i*k:s[v+k][u:u+5]='\//\____/\\'[k%2::2]
	if~-i:s[v][u+1+k]='_'
for l in s:print''.join(l)

オンラインでお試しください!

NeilのチャコールアプローチのPython変換。


これについては、ゴルフ用のPythonソリューションをご覧ください。Pythonの概念実証は900バイト以上でした!
ジェームズホルダーネス

3
+1+k-> -~k
ジョナサンフレッチ


5

Tcl、380 409バイト

ユーザーsergiolはこれを非常にうまく処理するのに忙しくしています。

set X [read stdin]
proc L {a b c d e s} {time {incr z
set y -1
time {incr y
set x -1
time {if {abs([set Z [lindex $::X [expr ($y+1)*11-[incr x]-1]]])==$z|$z<$Z} {set s [string repl [string repl $s [set i [expr -3*$x+57*$y-55*abs($z)+701]] $i+$b $a] [incr i $c] $i+$e $d]}} 11} 11} 12
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

オンラインでお試しください!

オリジナルコンテンツ

set xs [read stdin]
proc L {a b c d e s} {set z 0
while {[incr z]<12} {set y -1
while {[incr y]<11} {set x -1
while {[incr x]<11} {set Z [lindex $::xs [expr ($y+1)*11-$x-1]]
if {abs($Z)==$z||$z<$Z} {set i [expr -3*$x+57*$y-55*abs($z)+701]
set s [string repl [string repl $s $i $i+$b $a] [incr i $c] $i+$e $d]}}}}
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

オンラインでお試しください!

悲しいかな、それはそれです。「手に負えない」とき、それは目にやさしいだけです

set s [string repeat [string repeat " " 55]\n 23]

proc loops {s0 i0 io s1 i1} {
  set z  0; while {[incr z] < 12} {
  set y -1; while {[incr y] < 11} {
  set x -1; while {[incr x] < 11} {
    set Z [lindex $::xs [expr {($y+1) * 11 - $x - 1}]]
    if {abs($Z) == $z || $z < $Z} {
        set i [expr {-3*$x + 57*$y - 55*abs($z) + 701}]
        set ::s [string replace $::s $i $i+$i0 $s0]
        incr i $io
        set ::s [string replace $::s $i $i+$i1 $s1]
    }
  } } }
}

loops ""      -1 -55 \
       ___     2
loops /\\__\\  4  56 \
      \\/__/   4

puts $s

要件に従って文字列を作成します。stdinから配列を取得します。文字列データの上から下、上から下、右から左に移動します。2回のパスで行います。1回は上端に、もう1回は各立方体の残りの部分に。

私はいくつかの甘い機能的なラムダモジョを使用してそれを小さくしようとしましたが、悲しいかな、それはそれを大きくしました。


:あなたはゴルフができtio.run/...
sergiol

もっとゴルフ:tio.run/...
sergiol

もっと:tio.run/...
sergiol

さらにより:tio.run/...
sergiol

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.