XYZに沿って対称的に立方体の面を押し出す


33

サンドボックス

現在のタスクの目的のために、ユニット長の立方体は、次のようにASCIIシンボルを使用して斜め投影でレンダリングされます。

  +-----+
 /     /|
+-----+ |
|     | +
|     |/
+-----+
  • + 頂点のために。
  • -Xエッジの場合。Xに沿った単位の長さは-、2つの頂点間の5 で表されます。
  • |Yエッジの場合。Yに沿った単位の長さは、2 |つの頂点の間の2つで表されます。
  • /Zエッジ用。Zに沿った単位の長さは/、2つの頂点間の1つで表されます。
  • 頂点は、3つの平面すべてが交差する場所にのみ描画されます。
  • エッジは、正確に2つの平面が交差する場所にのみ描画されます。

単位面が押し出されると、元の位置から単位長だけオフセットされ、各方向(正と負)に4つの新しいエッジが作成されます。

押し出しは、各軸が断面1x1で長さnが(0,0,0)から離れた直方体として表される3Dデカルト座標系の軸を描くことと考えることができます。

Xに沿って1押し出し:

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

仕事

XYZ軸に3つの数値を指定し、指定された量だけ対称的に単位立方体の面を押し出し、上記のようにASCIIシンボルで結果をレンダリングします。

入力

x、y、z-非負の数-各軸の押し出しの長さ。0は押し出しがないことを意味します。入力には、3つの数字、3つの数字のリスト、トリプル、文字列、または便利なものを使用できます。

出力

押し出し後のキューブのASCII図面。先頭および末尾のwihtespacesは許可されます。

テストケース

X Y Z
0 0 0

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

1 0 0

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


0 0 1   
        +-----+
       /     /|
      /     / |
     /     /  +
    /     /  /
   /     /  /
  +-----+  /
  |     | / 
  |     |/
  +-----+


1 1 0

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

2 0 1

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

1 1 1 

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

受賞基準

すべての言語のバイト単位の最短ソリューションが勝ちです。使用した方法とコードの簡単な説明を追加してください。


各押し出しに上限はありますか?
無知の具現化

@Embodiment of Ignorance-9で十分
ガレンイワノフ

回答:


14

JavaScript(ES6)、 525 ... 475 471  459バイト

@Neilのおかげで13バイト節約

入力を配列として受け取ります[X,Y,Z]。文字のマトリックスを返します。

a=>([X,Y,Z]=a,m=[],W=X*6+Z*2,'1uol9h824lsqpq17de52u1okgnv21dnjaww111qmhx1gxf4m50xg6pb42kzijq21xyh34t0h2gueq0qznnza2rrimsg3bkrxfh3yrh0em').replace(/.{7}/g,s=>[[c,x,A,y,B,w,C,h,D,t]=parseInt(s,36)+s,Y*W,Z,X,Y|!W,Z*X,X*Y*!Z,X*Z*!Y,Y*Z*!X][c]&&(g=H=>V<h&&((m[r=y-(3-B)*p+(t>1?H-V:V)+Y*3+Z*2]=m[r]||Array(W*2+9).fill` `)[x-2*(3-A)*p+(t>1?V:H-V*t)+W]=` ${c>5?'  + ':t>1?'|-':'-|'}+/+`[(H%~-w?0:+t?4:2)|!(V%~-h)],g(++H<w?H:!++V)))(V=0,p=a[c%3],w-=-3*C*p,h-=-D*p))&&m

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

どうやって?

描画手順

出力は15面で構成され、特定の順序で描画されます。

アニメーション

実装

描画関数はgです。次のパラメーターで動作します。

  • (x,y):描画を開始する場所
  • w:幅
  • h:高さ
  • t:サイドのタイプ

頂点は常に描画されます。別のパラメーターc値に応じて、エッジが描画または消去されます。

場合はt=0、関数が前面に描画します。

...........      ...........
..+-----+..      ..+     +..
..|     |..  or  ..       ..
..|     |..      ..       ..
..+-----+..      ..+     +..
...........      ...........

t=1場合、上側を描画します。

...........      ...........
...+-----+.      ...+     +.
../     /..  or  ..       ..
.+-----+...      .+     +...
...........      ...........

t=2場合、右側を描画します。

......+....      ......+....
...../|....      .....  ....
....+ |....  or  ....+  ....
....| +....      ....  +....
....|/.....      ....  .....
....+......      ....+......

(x,y)(w,h)XYZ

c[1..8]

要約すると、サイドは次のように完全に説明されます。

{ctx=ox+mx×Py=oy+my×Pw=ow+mw×Ph=oh+mh×P

Pc

したがって、各側に次の10個のパラメーターを保存する必要があります。

[c,ox,mx,oy,my,ow,mw,oh,mh,t]

以下は、描画する必要がある15辺のパラメーターです。

sidecoxmxoymyowmwohmht0400237046014602346302226222403423366204030243062071240052220270341632600712301720222704008562224012294200370301101002370130111602313302126002070400137200070301148602040302

[0..9]

mバツmバツ+6/2mymy+3mwmw/3

結果として、正確に10桁の10桁の15桁の数値が生成され、36桁の7桁の15グループとして格納されます。

たとえば、最初の側はとしてエンコードされ4032070460、として保存され1uol9h8ます。


Array(W*2+9).fill` ` バイトを節約できると思います。
ニール

おっと、申し訳ありませんが、私の悪い、間違っているか何かを見たに違いありません。無視。
無知の

@EmbodimentofIgnorance心配ありません。:)
Arnauld

3
従来のクールな説明に加えて、優れた視覚化!尊敬!
ガレンイワノフ

@GalenIvanovありがとうございます!このチャレンジに取り組むのは本当に楽しかったです。
アーナウド

13

APL(Dyalog Classic)162 161 132 130バイト

{' |+/+ +-? ??? ++'[⍉(⊃~∘0)⍤13⍉↑a↑¨⍨↓(--1-⌊/∘,)2-/1⌽↑⍳⍴a←16|29|1+{2⊥+/¨∊¨=⌿¨⍵(⍉⍵)(⍉↓⍵)}⌺2 2 2{⍉⍤2⍉⌽0,⍵}⍣63/↓2/61<⍵+.=⍨↑⍳1+2×⍵]}

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

  • 単位立方体の3Dブール配列を生成する
  • xyzに沿って各キュービック6 3 2回複製
  • ゼロで囲む
  • 各2×2×2サブアレイについて、対応する出力文字を決定する0〜16の数値を計算します。(1 + 4*cx + 2*cy + cz) mod 16ここでcxcyczから構成され、その軸に沿って同一の値「ロッド」の数は、軸X、Y、Zに沿っている、すなわちベクトル同じ値:0 0または1
  • 各セルについて、対応する文字を画面上で描画する場所を計算します
  • セルごとに、不透明な「ピクセル」を1つだけ含む透明な(0で埋められた)マトリックスを作成します
  • マトリックスを混合します-この時点で、次元がinx、iny、inz、outx、outyの5D配列があります
  • 最初の3つの軸を縮小し、最初の非透明(≠0)アイテムのみを維持します
  • ルックアップテーブル(文字列)を使用して、数値を -|/+

おかげでスコット・ミルナー、いくつかのことをスポッティングのための+Sのようにレンダリングされた?S


これを実際にどのようにテストしますか?たとえば、2,3,4の押し出しを試してみたかったのですが、うまくいくように見えるものは何もありませんでした。
ニール

アルゴは非常に無駄が多いため、2 3 4がメモリ不足になりますが、2 3 3は手の届く範囲にあります
ngn

@Neil私は小さな修正を行い、2 3 4が動作するようになりました。副作用として1バイトを失った:)
ngn

Ascii-artチャレンジのチャコールの半分の長さのAPLソリューション?!どうしたの?!
シャギー

3
100%確かではありませんが、これは0 1 1
Scott Milner

6

、325バイト

≔×⁶Nθ≔׳Nη≔⊗Nζ¿‹¹№⟦θηζ⟧⁰«B⁺⁷⊗θ⁺⁴⊗η↗↗⊕⊗ζ+⁺⁵⊗θP↙⊗⊕ζ↓+↓⁺²⊗η↙+↙⊕⊗ζ»«F‹⁰θ«↗+↗←+←⊖θ↙+/P→θ↓+↓²+⊖θ+»F‹⁰η«J⁶¦³↗+↗↓+↓⊖η↙+/P↑η←+←⁵↑+↑⊖η+»F‹⁰ζ«J⁸±²↓+↓↓↗+↗⊖ζ↑+↑²P↙ζ←+←⁵↙+↙⊖ζ+»J⁶¦⁰F‹⁰ζ«G↓³↙⊕ζ←⁷↑³↗⊕ζ ↙+↙⊖ζ↓+↓²+→⁵P↗ζ↑+↑²P←⁶↗+↗⊖ζ»F‹⁰η«G←⁶↑⊕η↗³→⁶↓⊕η ↑+↑⊖η←+←⁵↙+/P↓η+⁵P↗²↓+↓⊖η»F‹⁰θ«G↗²→⊕θ↓⁴↙²←⊕θ →+⊖θ↗+/↑+↑²P←θ↙+/P↓³←+←⊖θ»P↗∧∧θη²P↓∧∧ζθ³P←∧∧ηζ⁶+

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

≔×⁶Nθ≔׳Nη≔⊗Nζ

押し出しを入力しますが、事前に乗算してバイトを節約します。

¿‹¹№⟦θηζ⟧⁰«B⁺⁷⊗θ⁺⁴⊗η↗↗⊕⊗ζ+⁺⁵⊗θP↙⊗⊕ζ↓+↓⁺²⊗η↙+↙⊕⊗ζ»«

少なくとも2つの押し出しがゼロの場合、単純に寸法(2x + 1、2y + 1、2z + 1)の直方体を描画します。さもないと:

F‹⁰θ«↗+↗←+←⊖θ↙+/P→θ↓+↓²+⊖θ+»

左側の押し出しがある場合は印刷します。

F‹⁰η«J⁶¦³↗+↗↓+↓⊖η↙+/P↑η←+←⁵↑+↑⊖η+»

ダウン押出しがある場合は印刷します。

F‹⁰ζ«J⁸±²↓+↓↓↗+↗⊖ζ↑+↑²P↙ζ←+←⁵↙+↙⊖ζ+»

背面押し出しがある場合は印刷します。

J⁶¦⁰

残りの押し出しはすべてこの時点で出会います(最後まで描画されません!)

F‹⁰ζ«G↓³↙⊕ζ←⁷↑³↗⊕ζ ↙+↙⊖ζ↓+↓²+→⁵P↗ζ↑+↑²P←⁶↗+↗⊖ζ»

前面の押し出しがある場合は、左と下の押し出しの重なり合う部分を消去するように注意して印刷します。

F‹⁰η«G←⁶↑⊕η↗³→⁶↓⊕η ↑+↑⊖η←+←⁵↙+/P↓η+⁵P↗²↓+↓⊖η»

上にある押し出しがある場合は、背面の押し出し部分と残っている押し出し部分を消去するように注意して印刷します。

F‹⁰θ«G↗²→⊕θ↓⁴↙²←⊕θ →+⊖θ↗+/↑+↑²P←θ↙+/P↓³←+←⊖θ»

正しい押し出しがある場合は、ダウン押し出しとバック押し出しの重なり合う部分を消去するように注意して印刷します。

P↗∧∧θη²P↓∧∧ζθ³P←∧∧ηζ⁶+

後者の押し出し間の結合を描画します。


木炭で325バイト?!オンアスキー・アートの挑戦!Ja(vaScri)ptでこれを試みさえしないようにするのに十分です!
シャギー

@Shaggyこれは最適なアプローチではないかもしれませんし、とにかく見落としているゴルフをする方法があるかもしれません。ngnのメソッドは興味をそそられるように見えますが、形状を内部配列に描画し、エッジ検出を実行して出力を生成するように見えます。
ニール

@Shaggy 195バイトのソリューションを思いつきました。これはまったく異なるアプローチであるため、個別に投稿しました。ただし、APLにはまだ十分ではありません。
ニール

3

木炭195の 164 144バイト

≔⁺³×⁶Nθ≔⁺²×³Nη≔⊕⊗NζF…·±ζζF…·±ηηF…·±θθ«J⁻λι⁺κι≔⟦⟧δFE²↔⁻⁺ιμ·⁵FE²↔⁻κνFE²↔⁻⁺λξ·⁵⊞δ⌊⟦‹μζ‹νη‹ξθ‹¹№E⟦μνξ⟧‹π⊕ρ¹⟧≡Σδ¹+²§ |-/⁺⌕δ¹⌕⮌δ¹¦³+⁴§ +Σ…δ⁴¦⁶§ |-/⌕δ⁰

オンラインでお試しください!リンクは、コードの詳細バージョンです。これは、押し出しを描画するためにまったく異なるアプローチを使用するため、別個の回答として投稿しています。説明:

≔⁺³×⁶Nθ≔⁺²×³Nη≔⊕⊗Nζ

押し出しを入力し、囲む直方体のサイズの半分を計算しますが、Charcoalの範囲は常に整数であるため、整数演算で計算します。出力の原点は、元のユニットキューブの中心にマッピングされます。

F…·±ζζF…·±ηηF…·±θθ«

押し出しを含む直方体内(境界を含む)のすべての座標をループします。

J⁻λι⁺κι

それらの座標に対応する出力位置にジャンプします。

≔⟦⟧δFE²↔⁻⁺ιμ·⁵FE²↔⁻κνFE²↔⁻⁺λξ·⁵⊞δ⌊⟦‹μζ‹νη‹ξθ‹¹№E⟦μνξ⟧‹π⊕ρ¹⟧

指定された座標から、8つの対角線方向すべてをのぞいて、その方向で押し出しが重なるかどうかを判断します。ピーク座標がまだ直方体内にあることを確認し、元の立方体内にある座標の軸の数が1より大きくなければなりません。立方体の表示の高さが奇数であるため、Y軸の値はピークされるのは整数であり、他の軸は分数座標を使用します。

≡Σδ

押し出しが重なる方向の数を考慮します。ゼロの場合のように何かを印刷したい場合は5つの興味深いケースがあります。つまり、これは空のスペースであり、何も印刷したくないことを意味します。一方、8の場合は、押し出しや印刷したものはすべて、アイポイントに近いレイヤーでオーバープリントされます。

¹+

押し出しが一方向にのみ重なる場合、これは外側の角であり、aを出力する必要があります+

²§ |-/⁺⌕δ¹⌕⮌δ¹¦

押し出しが2方向で重なっている場合、これは外縁です。どの種類のエッジが、2つのオーバーラップ間の分離から決定されます。6と7は後ろ向きのエッジであり、上書きされます。4は斜めのエッジ、2は垂直のエッジ、1は水平のエッジです。(実際は7から分離を差し引いた値を計算する方が簡単だと思われます。)

³+

押し出しが3つの方向に重なる場合、これは押し出しの1つがゼロで、aを出力する必要がある場合の内側の角+です。

⁴§ +Σ…δ⁴¦

押し出しが4方向に重なっている場合、2つのケースがあります:面(任意の方向)、および3つの押し出しの場合の内側の角。後者の場合、視聴者に向かって重複する奇数の数があります。

⁶§ |-/⌕δ⁰

押し出しが6方向で重なっている場合、これは内側のエッジです。2つの空のスペースの1つが視点(配列の最後のエントリ)に向かう方向である場合にのみ関心があることを除いて、外縁の補数のように機能します。


2

K(ngn / k)、172バイト

{s:1+|/'i-:&//i:1_--':1_4#!#'2*:\a:16!29!1+2/(!3){+'+x}/'{2+':''1+':'0=':x}'{++'x}\6{+'+0,|x}/{6}#{3}#'{2}#''s#1<+/x=!s:1+2*x;" |+/+ +-? ??? ++"s#@[&*/s;s/i;{x+y*~x};,//a]}

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

私のAPLソリューションの義務的なK書き換え

同じアルゴリズム。ただし、3d-> 2dレンダリングは、3d要素ごとに2dマトリックスを作成して混合する代わりに、(kに相当する)散布インデックス割り当てで行われます


ソリューションngn/aplと比較してパフォーマンスはどうDyalog APLですか?
ガレンイワノフ

@GalenIvanovそれは私のAPL溶液中で、私はいくつかのバイトを保存するために多くのメモリを無駄にしているため、公正比較すること、そしてkで短くないだろう。この場合にはより高速であることを起こる
NGN

あなたのAPL / Dyalog 1およびNGN / APLにおける仮想的なソリューション-私は2つのAPLのソリューションとの比較について尋ねた
ガレン・イワノフ

おっと、なぜそれを「ngn / k」と読むのかわかりません...再び不公平です-ngn / aplは趣味のJavaScriptであり、dyalogはプロフェッショナルですc
ngn

1
@GalenIvanovはおそらくそうではありません。NGN / APLは、(ランクオペレータのような言語に最近追加が欠落している()およびステンシル
NGN
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.