Bir küpün yüzlerini XYZ boyunca simetrik olarak çıkar


33

Kum havuzu

Mevcut görevin amaçları doğrultusunda, ASCII sembolleriyle eğik çıkıntıda birim uzunluktaki bir küp oluşturulur:

  +-----+
 /     /|
+-----+ |
|     | +
|     |/
+-----+
  • + köşeleri için.
  • -X kenarları için. X boyunca birim uzunluk -iki köşe arasında beş ile temsil edilir .
  • |Y kenarları için. Y boyunca birim uzunluk iki ile temsil edilir.| iki köşe arasında iki .
  • /Z kenarları için. Z boyunca birim uzunluk bir/ iki köşe arasında bir değer ile gösterilir.
  • Vertices, yalnızca üç düzlemin kesiştiği yerde çizilir.
  • Kenarlar, yalnızca iki düzlemin kesiştiği yerde çizilir.

Bir ünite yüzü ekstrüde edildiğinde, orijinal konumundan ünite uzunluğuyla dengelenir ve her yön için dört yeni kenar oluşturulur (pozitif ve negatif).

Ekstrüzyonu, her bir eksenin 1x1 kesitli ve uzunluğu n(0,0,0) uzağında olan bir küboid olarak temsil edildiği bir 3D Kartezyen koordinat sisteminin eksenlerinin çizilmesi olarak düşünebilirsiniz.

X boyunca 1 ile ekstrüzyon:

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

Görev

XYZ eksenleri için üç sayı verildiğinde, birim küpün yüzlerini belirtilen miktarlarda simetrik olarak çıkarınız ve sonucu yukarıda belirtildiği gibi ASCII sembolleriyle veriniz.

Giriş

x, y, z - negatif olmayan sayılar - ilgili eksenler için ekstrüzyon uzunlukları. 0 ekstrüzyon yok demektir. Girdi, üç sayı, üç sayının listesi, üçlü, bir dize veya sizin için uygun olan herhangi bir şey olabilir.

Çıktı

Ekstrüzyondan sonra küpün ASCII çizimi. Önde gelen ve takip eden boşluklara izin verilir.

Test durumları

X Y Z
0 0 0

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

1 0 0

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


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


1 1 0

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

2 0 1

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

1 1 1 

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

Kazanan kriterler

Her dilde bayt cinsinden en kısa çözüm kazanır. Lütfen kullanılan yöntemin ve kodunuzun kısa bir açıklamasını ekleyin.


Her ekstrüzyon için bir üst sınır var mı?
Cehalet Daveti

@ Cehalet Daveti - 9 yeterli olmalı
Galen Ivanov

Yanıtlar:


14

JavaScript (ES6),  525 ... 475 471  459 bayt

@Neil sayesinde 13 bayt kaydedildi

Diziyi girdi olarak alır [X,Y,Z]. Bir karakter matrisi döndürür.

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

Çevrimiçi deneyin!

Nasıl?

Çizim adımları

Çıktı, belirli bir sırayla çizilen 15 taraftan oluşur.

animasyon

uygulama

Çizim fonksiyonu g . Aşağıdaki parametrelerle çalışır:

  • (x,y) : çizime nereden başlanır
  • w : genişlik
  • h : yükseklik
  • t : yan taraf

Köşeler daima çizilir. Başka bir c parametresinin değerine bağlı olarak, kenarlar çizilir veya silinir.

Eğer t=0 , fonksiyon bir ön tarafı çizer:

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

Eğer t=1 , üst kısmı çizer:

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

t=2

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

(x,y)(w,h)XYZ

Hem kullanılacak değişken hem de kontrol edilecek koşul parametre ile tanımlanır c[1..8]

Özetlemek gerekirse, bir taraf tam olarak şöyle tarif edilir:

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

Pc

Bu nedenle, her bir taraf için aşağıdaki 10 parametreyi kaydetmemiz gerekir:

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

Aşağıda, çizilmesi gereken 15 tarafın parametreleri verilmiştir:

sidecoxmxoymyowmwohmht0400237046014602346302226222403423366204030243062071240052220270341632600712301720222704008562224012294200370301101002370130111602313302126002070400137200070301148602040302

[0..9]

mx(mx+6)/2mymy+3mwmw/3

Tabanda 36 7 basamaklı 15 grup halinde depolanan, tam olarak 10 basamaklı 15 sayı ile sonuçlanır.

Örneğin, birinci taraf olarak kodlanır 4032070460ve olarak saklanır 1uol9h8.


Sanırım Array(W*2+9).fill` ` bir bayt kurtarıyor.
Neil,

Hata! Üzgünüm, benim hatam, yanlış bir şey görmem gerekiyor. İptal.
Cehalet

@EmbodimentofIgnorance Endişelenmeyin. :)
Arnauld

3
Geleneksel olarak serin açıklamanıza ek olarak mükemmel görselleştirme! Saygı!
Galen Ivanov

@GalenIvanov Teşekkürler! Bu sorun üzerinde çalışmaktan gerçekten zevk aldım.
Arnauld,

13

APL (Dyalog Klasik) , 162 161 132 130 bayt

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

Çevrimiçi deneyin!

  • 3d bool birim küp dizisi oluşturmak
  • xyz boyunca her bir küp 6 6 2 kez çoğalt
  • sıfırlarla kuşatmak
  • Her 2 x2 x 2 altdizilim işlem tekabül eden çıkış kömürü belirleyen, 0 ile 16 arasında bir sayı: (1 + 4*cx + 2*cy + cz) mod 16burada cx,cy ,cz oluşan bu eksen boyunca aynı değer "çubuk" sayısı ekseni x, y, z ekseni boyunca olan, örneğin, vektörler aynı değerde: 0 0 veya 1 1. alt dizinin tümü sıfırsa (veya hepsi bir - hepsi önemli değilse) bir istisna yaparız ve bunun yerine 28 sayısını 0 olarak kabul ederiz.
  • Her hücre için karşılık gelen karakterin ekranda çizilmesi gereken hesaplama
  • Her hücre için sadece bir opak "piksel" içeren şeffaf (0-yastıklı) bir matris oluşturun
  • matrisleri karıştır - bu noktada inx, iny, inz, outx, outy boyutlarına sahip bir 5d dizisine sahibiz
  • sadece ilk saydam olmayan (≠ 0) öğeyi yanlarında tutarak ilk üç ekseni azaltın
  • sayıları dönüştürmek için bir arama tablosu (bir dize) kullanın. -|/+

teşekkürler Scott Milner bazı olduğunu tespit için +ler olarak işlenen ?s


Bunu gerçekten nasıl test ediyorsunuz? Örneğin 2,3,4 ekstrüzyonları denemek istedim, ancak bariz hiçbir şey işe yaramadı.
Neil

Algo çok savurgandır, bu yüzden 2 3 4 hafızası
tükenir

@Neil küçük bir düzeltme yaptım ve şimdi 2 3 4 çalışıyor. yan etki olarak bir bayt kaybetti :)
ngn

Eski bir sanat mücadelesinde Kömürün yarısı kadar olan bir APL çözümü ?! Neler oluyor?!
Shaggy

3
% 100 emin değil, ama 0 1 1 '
Scott Milner

6

Kömür , 325 bayt

≔×⁶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←∧∧ηζ⁶+

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

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

Ekstrüzyonları girin, fakat baytları kurtarmak için önceden doldurun.

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

Ekstrüzyonlardan en az ikisi sıfırsa, basitçe boyutlardan bir küboid çizin (2x + 1, 2y + 1, 2z + 1). Aksi takdirde:

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

Varsa sol ekstrüzyonunu yazdırın.

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

Varsa aşağı ekstrüzyonunu yazdırın.

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

Varsa arka ekstrüzyonu yazdırın.

J⁶¦⁰

Kalan ekstrüzyonların hepsi bu noktada buluşuyor (sonuna kadar çekilmiyor!)

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

Varsa, önden ekstrüzyonu yazdırın, sol ve aşağı ekstrüzyonların üst üste gelebilecek parçalarını silmeye dikkat edin.

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

Üst üste binebilecek arka ve sol ekstrüzyon parçalarını silmek için özen göstererek varsa ekstrüzyonun baskısını alın.

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

Üst üste gelebilecek aşağı ve arka ekstrüzyon parçalarını silmeye özen göstererek, varsa sağ ekstrüzyonu yazdırın.

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

Son ekstrüzyonlar arasındaki birleşimleri çizin.


Kömürde 325 bayt mı ?! Üzerinde ascii-art meydan ?! Bunu Ja (vaScri) pt de denememe bile zorlamıyor!
Shaggy

@Shaggy Bu, optimal bir yaklaşım olmayabilir ve yine de gözardı ettiğim golf yöntemleri olabilir. Ngn'in metodu ilgi çekici görünmekle birlikte, şekli bir iç diziye çekiyormuş gibi görünüyor ve daha sonra çıktısını elde etmek için kenar algılaması yapıyor gibi görünüyor.
Neil

@Shaggy Tamamen farklı bir yaklaşım olduğu için ayrı ayrı gönderdiğim 195 baytlık bir çözüm buldum. Yine de APL hala iyi.
Neil

3

Kömür , 195 164 144 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Bunu ekstrüzyonun çizilmesinde tamamen farklı bir yaklaşım kullandığından ayrı bir cevap olarak gönderiyorum. Açıklama:

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

Ekstrüzyonları girin ve kapalı küboidin yarısı büyüklüğünü hesaplayın, ancak tamsayı aritmetikte çünkü Kömürün aralıkları her zaman tamsayıdır. Çıktının kökeni, orijinal birim küpünün merkezine eşlenir.

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

Ekstrüzyon içeren küboid içindeki (sınır dahil) tüm koordinatlar üzerinde döngü yapın.

J⁻λι⁺κι

Bu koordinatlara karşılık gelen çıkış konumuna atlayın.

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

Verilen koordinatlardan, ekstrüzyonun bu yönde çakışıp çakışmadığını belirlemek için sekiz çapraz yöne de göz atın. Bakılmış koordinatlar hala küboid içinde olduklarını kontrol eder ve daha sonra koordinatın orijinal küp içinde bulunduğu eksen sayısının 1'den büyük olması gerekir. Küpün tuhaf bir ekran yüksekliğine sahip olması nedeniyle, Y ekseni değerlerinin dikilenler tamsayılar, diğer eksenler kesirli koordinatlar kullanıyor.

≡Σδ

Ekstrüzyonun çakıştığı yönlerin sayısını düşünün. Sıfır durumunda olduğu gibi, bir şey yazdırmak istediğimiz beş ilgi alanı vardır, bu, bunun boş alan olduğu ve sekizde olduğu zaman hiçbir şeyin yazdırılmasını istemediğimiz anlamına gelir. Ekstrüzyon ve bastığımız her şey göz noktasına yakın bir katmanla üst üste yazdırılır.

¹+

Ekstrüzyon sadece bir yönde üst üste binerse, bu bir dış köşedir ve a çıkışına ihtiyacımız var +.

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

Ekstrüzyon iki yönde üst üste binerse, bu dış kenardır. İki örtüşme arasındaki ayrımdan hangi tür kenarlar belirlenir; Şekil 6 ve 7 arkaya dönük kenarlardır ve üzerine yazılacaktır, 4'ü köşegen bir kenardır, 2 dikey kenardır ve 1 yatay kenardır. (Aslında 7 eksi ayrımı hesaplamak daha kolay görünüyor gibi hesaplarım.)

³+

Ekstrüzyon üç yönde üst üste binerse, bu ekstrüzyonlardan birinin sıfır olduğu durumda bir iç köşedir ve a çıkışı vermemiz gerekir +.

⁴§ +Σ…δ⁴¦

Ekstrüzyon dört yönde üst üste binerse, iki durum vardır: yüzler (herhangi bir yön) ve üç pozitif ekstrüzyonlu durumda iç köşeler. İkinci durumda, izleyiciye yönelik çok sayıda çakışma vardır.

⁶§ |-/⌕δ⁰

Ekstrüzyon altı yönde üst üste binerse, bu bir iç kenardır. Dıştaki bir kenarın tamamlayıcısı gibi çalışır, ancak yalnızca iki boş alandan birinin göz noktasına (dizideki son giriş) doğru olan yönle ilgilenmesi dışında ilgileniriz.


2

K (ngn / k) , 172 bayt

{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]}

Çevrimiçi deneyin!

zorunlu k yeniden yazmak benim apl çözümümün

Aynı algoritma, her 3d eleman için 2d matrisler oluşturmak ve bunları karıştırmak yerine, 3d -> 2d görüntülemenin (k eşdeğeri) scatter index atama ile yapılması dışında


ngn/aplÇözümünüze kıyasla perfromunuz nasıl Dyalog APL?
Galen Ivanov

@GalenIvanov adil bir karşılaştırma olmazdı çünkü apl çözümümde birkaç byte tasarruf etmek için çok fazla hafıza harcıyorum ve k
kısacası

İki APL çözümü - sizinki APL / Dyalog one ve ngn / apl'deki varsayımsal bir çözüm arasındaki karşılaştırmayı sordum
Galen Ivanov

ayy, neden "ngn / k" olarak okuduğumu bilmiyorum ... yine haksızlık - ngn / apl hobi javascript, dyalog profesyonel c
ngn

1
@GalenIvanov muhtemelen değil. ngn / apl rütbe operatörü ( ) ve stencil ( ) gibi dile yeni eklenenler eksik
ngn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.