อาคารบล็อก 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 แสดงบนหน้าจอโดยตรงหรือส่งคืนเป็นสตริงที่คั่นด้วยบรรทัดใหม่

อนุญาตช่องว่างนำหน้าและต่อท้าย

กฎอาคาร

รูปร่างของบล็อก 3 มิติแต่ละแบบมีลักษณะดังนี้:

 ___
/\__\
\/__/

และก้อนสี่เหลี่ยมขนาด 2x2x2 มีลักษณะดังนี้:

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

เมื่อบล็อกทับซ้อนกันบล็อกที่สูงกว่าจะมีความสำคัญมากกว่าบล็อกที่ต่ำกว่าบล็อกที่อยู่ด้านหน้าจะมีความสำคัญมากกว่าบล็อกที่อยู่ด้านหลังถัดไปและบล็อกทางด้านซ้ายจะมีความสำคัญมากกว่าบล็อกที่อยู่ทางด้านขวา กรณีพิเศษเพียงอย่างเดียวคือบรรทัดบนสุดของบล็อกไม่ควรเขียนทับอักขระที่ไม่ใช่ช่องว่างด้านหลัง

การอธิบายความสูงของคอลัมน์สามารถอธิบายได้ดีที่สุดโดยดูจากการแสดงภาพ 2 มิติจากด้านข้าง

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

กรณีทดสอบ

หากคุณต้องการลองวิธีแก้ปัญหาของคุณกับอินพุตอีกสองสามข้อฉันได้รวบรวมกรณีทดสอบสองสามข้อไว้ที่นี่

การชนะ

นี่คือดังนั้นการส่งที่สั้นที่สุด (เป็นไบต์) ชนะ


9
Ohh boy เตรียมตัวให้พร้อมสำหรับโซลูชั่น 300 ไบต์ ความท้าทายที่ดี +1
มนุษย์โดยรวม

7
@tallyallyhuman Nah, Dennis กำลังจะมีวิธีแก้ปัญหาแบบ 9 ไบต์ใน 20 นาที
ผู้ดูแลวัด

3
มุมมองจะต้องเป็นตามที่แสดงด้านล่างซ้ายของข้อมูลอินพุตในเบื้องหน้าหรือไม่? ความจริงที่ว่านี่ไม่ใช่องค์ประกอบแรกหรือสุดท้ายของข้อมูลทำให้มันยากขึ้น เป็นที่ยอมรับได้หรือไม่ 1. เก็บการแมปตามที่เป็นอยู่และดึงเอาท์พุทด้วยคอลัมน์ด้านล่างขวาในเบื้องหน้าหรือ 2. วาดภาพสะท้อนในกระจกหรือหมุน 90 องศาของข้อมูล? สิ่งเหล่านี้จะทำให้องค์ประกอบข้อมูลสุดท้ายสอดคล้องกับคอลัมน์ในเบื้องหน้าซึ่งจะง่ายขึ้น
ระดับแม่น้ำ St

3
ฉันรู้สึกอยากใช้เครื่องมือเกมจริง (หรือส่วนหนึ่งของมัน) ในการแสดงภาพและแปลงเป็น ASCII
Stan Strum

@LevelRiverSt ที่ดูเหมือนว่าคำขอที่สมเหตุสมผล - คุณสามารถเลือกลำดับขององค์ประกอบอินพุต 121 รายการที่เหมาะสมที่สุดสำหรับโซลูชันของคุณตราบใดที่การสั่งซื้อของคุณสอดคล้องกัน ต้องเป็นไปได้ที่จะสร้างเลย์เอาต์ทุกรูปแบบที่สามารถสร้างได้ด้วยลำดับเริ่มต้น
James Holderness

คำตอบ:


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เป็น a 33ฉันได้รับเพียง 11 บล็อกในหอคอย ในหอคอยทั่วไปดูเหมือนจะปกคลุมที่ 11 จะเกิดอะไรขึ้น?
Fabian Röling

@Fabian ฉันสับสนเล็กน้อยที่F¹¹F¹¹F¹¹ไม่ได้เงื่อนงำ ...
นีล

ฉันไม่รู้ภาษาการเขียนโปรแกรมนี้ฉันเล่นเพียงเล็กน้อยด้วยลิงค์ TIO
Fabian Röling

30

C,  376   350   313   309  285 ไบต์

ขอบคุณ @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?
Jonathan Frech

@ JonathanFrech แน่นอนว่าฉันลืมเรื่องนั้นไป
Steadybox

*s==32*s<33->
Jonathan Frech

for(e=k=1;e;++k)for(e=for(k=1;e;++k)for(e=->
Jonathan Frech

#define B b(...)&++e-> #define B++e&b(...)(สมมติbว่าไม่ได้ขึ้นอยู่กับeซึ่งฉันคิดว่ามันไม่ได้)
Jonathan Frech

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`
`)

ที่บันทึกไว้ 26 ไบต์จาก@ ข้อเสนอแนะของนีล

Ungolfed

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

@ 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)

ลองออนไลน์!

Python การแปลของวิธีการของ Neil


ยินดีที่ได้เห็นโซลูชัน Python แบบ golfed สำหรับสิ่งนี้ Python ของฉันพิสูจน์แนวคิดได้มากกว่า 900 ไบต์!
James Holderness

3
+1+k-~k->
Jonathan Frech


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

ลองออนไลน์!

อนิจจามันเป็นสิ่งที่มันเป็น มันง่ายกว่าการมองตาเพียงเล็กน้อยเมื่อ“ ungolfed”

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 ไปจากด้านล่างไปด้านบนด้านหน้าไปด้านหลังขวาไปซ้ายเหนือข้อมูลสตริง ทำในสองรอบครั้งเดียวสำหรับขอบด้านบนและอีกครั้งสำหรับส่วนที่เหลือของร่างกายของแต่ละก้อน

ฉันพยายามทำให้มันเล็กลงโดยใช้แลมบ์ดาโมโจที่แสนหวานแต่ทว่านั่นทำให้มันใหญ่ขึ้น


คุณสามารถเล่นกอล์ฟ: tio.run/…
sergiol

การเล่นกอล์ฟเพิ่มเติม: tio.run/…
sergiol

เพิ่มเติม: tio.run/…
sergiol

ยังมีอีกมาก: tio.run/…
sergiol

เพิ่มเติมเลย: tio.run/##lVHtboJAEPx/ …
sergiol
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.