เศษส่วนต้นไม้ไบนารี


25

ความท้าทายในวันนี้คือการวาดต้นไม้ไบนารีเป็นที่สวยงามอย่างเช่น:

                               /\
                              /  \
                             /    \
                            /      \
                           /        \
                          /          \
                         /            \
                        /              \
                       /                \
                      /                  \
                     /                    \
                    /                      \
                   /                        \
                  /                          \
                 /                            \
                /                              \
               /\                              /\
              /  \                            /  \
             /    \                          /    \
            /      \                        /      \
           /        \                      /        \
          /          \                    /          \
         /            \                  /            \
        /              \                /              \
       /\              /\              /\              /\
      /  \            /  \            /  \            /  \
     /    \          /    \          /    \          /    \
    /      \        /      \        /      \        /      \
   /\      /\      /\      /\      /\      /\      /\      /\
  /  \    /  \    /  \    /  \    /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

คุณจะได้รับจำนวนเต็มบวกเป็นอินพุต การป้อนข้อมูลนี้เป็นความสูงของต้นไม้ ตัวอย่างข้างต้นมีความสูงหก

คุณสามารถส่งได้ทั้งแบบเต็มรูปแบบโปรแกรมหรือฟังก์ชั่นและคุณมีอิสระในการใช้ใด ๆ ของเราวิธีการ IO เริ่มต้น ตัวอย่างเช่นการพิมพ์ต้นไม้กลับสตริงที่มีการขึ้นบรรทัดใหม่กลับอาร์เรย์ 2d ถ่านการบันทึกต้นไม้เป็นไฟล์และอื่น ๆ ทั้งหมดจะได้รับอนุญาต

อนุญาตให้เว้นวรรคต่อท้ายในแต่ละบรรทัด

นี่คือตัวอย่างของอินพุตและเอาต์พุตที่สอดคล้องกัน:

1:
/\

2:
 /\
/\/\

3:
   /\
  /  \
 /\  /\
/\/\/\/\

4:
       /\
      /  \
     /    \
    /      \
   /\      /\
  /  \    /  \
 /\  /\  /\  /\
/\/\/\/\/\/\/\/\

5:
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

น่าเสียดายที่เอาต์พุตเติบโตแบบทวีคูณดังนั้นจึงยากที่จะแสดงตัวอย่างขนาดใหญ่ขึ้น นี่คือลิงค์ไปยังเอาต์พุตสำหรับ 8

ตามปกตินี่เป็นความท้าทายของการดังนั้นช่องโหว่มาตรฐานจึงมีผลบังคับใช้และพยายามเขียนโปรแกรมสั้นที่สุดเท่าที่จะเป็นไปได้สำหรับภาษาที่คุณเลือก

มีความสุขในการเล่นกอล์ฟ!


สามารถมีช่องว่างต่อท้ายเพื่อให้ทุกบรรทัดมีความยาวเท่ากันได้หรือไม่?
xnor

@xnor ใช่นั่นเป็นเรื่องปกติ
DJMcMayhem

คำตอบ:


5

Python 2, 77 ไบต์

S=s=i=2**input()
while s:print S/s*('/'+' '*(s-i)+'\\').center(s);i-=2;s/=s/i

พิมพ์ด้วยช่องว่างต่อท้ายยกเลิกด้วยข้อผิดพลาด

ฉันใช้รหัสนี้จากการส่งของฉันถึงความท้าทายที่ฉันโพสต์บน Anarchy Golfรวมถึงการปรับปรุงหนึ่งไบต์ที่ xsot พบ ค่า hardcoded 128 2**input()ก็เปลี่ยนไป

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

แต่ละเซกเมนต์มี a /และ\มีช่องว่างในระหว่างเช่นเดียวกับด้านนอกเพื่อแผ่นความยาวที่เหมาะสม centerช่องว่างภายในนอกจะทำด้วย

ตัวแปรsติดตามปัจจุบันที่มีของแต่ละส่วนงานและจำนวนของกลุ่มคือเพื่อให้ความกว้างทั้งหมดคือความกว้างต้นไม้S/s Sหมายเลขบรรทัดiนับถอยหลังด้วย 2 และเมื่อใดก็ตามที่ค่าsครึ่งหนึ่งจะเกิดการแบ่งและความกว้างของส่วนจะลดลงครึ่งหนึ่ง s/=s/iนี้จะกระทำผ่านการแสดงออก เมื่อiถึง0จะทำให้เกิดข้อผิดพลาดที่ยกเลิกโปรแกรม

เนื่องจาก anagolf อนุญาตให้ส่งโปรแกรมเท่านั้นฉันจึงไม่ได้สำรวจความเป็นไปได้ของฟังก์ชันเรียกซ้ำซึ่งฉันคิดว่าน่าจะสั้นกว่า




3

Haskell , 140 138 135 ไบต์

e n=[1..n]>>" "
n!f=(e n++).(++e n)<$>f
f 0=[]
f n=1!f(n-1)++['/':e(2*n-2)++"\\"]
b n|n<2=f 1|t<-b$n-1,m<-2^(n-2)=m!f m++zipWith(++)t t

ลองออนไลน์! โทรด้วยb 5ส่งคืนรายการสตริง

การใช้งานการพิมพ์ที่ดี:

*Main> putStr . unlines $ b 5
               /\
              /  \
             /    \
            /      \
           /        \
          /          \
         /            \
        /              \
       /\              /\
      /  \            /  \
     /    \          /    \
    /      \        /      \
   /\      /\      /\      /\
  /  \    /  \    /  \    /  \
 /\  /\  /\  /\  /\  /\  /\  /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

(บางคน) คำอธิบาย:

  • e nสร้างสตริงของnช่องว่าง
  • n!fคั่นแต่ละสตริงในรายการของสตริงfด้วยnช่องว่างด้านซ้ายและขวา
  • f nวาด "จุดสูงสุด" ในnโดย2nสี่เหลี่ยม
  • b n ดึงต้นไม้ไบนารีด้วยการต่อต้นไม้เล็กสองต้นเข้าด้วยกัน

แก้ไข: -3 ไบต์ขอบคุณ Zgarb!


ฉันคิด1!f(n-1)และm!f mควรบันทึกสองสามไบต์
Zgarb

@Zgarb ขอบคุณที่ชี้ให้เห็นบางครั้งกฎความสำคัญเหล่านั้นอาจทำให้เกิดความสับสน
Laikoni

2

J , 49 43 42 ไบต์

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))

สิ่งนี้จะประเมินเป็นคำกริยาที่ใช้ตัวเลขและส่งกลับอาร์เรย์อักขระแบบ 2D ลองออนไลน์!

คำอธิบาย

ฉันแรกสร้างเมทริกซ์ของค่า -1, 0 และ 1 โดยทำซ้ำกริยาช่วยแล้วแทนที่ตัวเลขด้วยตัวอักษร กริยาช่วยสร้างครึ่งทางขวาของการทำซ้ำครั้งถัดไปจากนั้นสะท้อนในแนวนอนเพื่อสร้างส่วนที่เหลือ ในคำอธิบายต่อไปนี้,เชื่อมอาร์เรย์ 2 มิติในแนวตั้งและ 1D ในแนวนอน

' /\'{~(|.,-)"1@(=@i.@#,-)^:(<:`(,:@,&*-))  Input is n.
                          ^:(            )  Iterate this verb
                             <:             n-1 times
                               `(       )   starting from
                                    ,&*-    the array 1 -1 (actually sign(n), sign(-n))
                                 ,:@        shaped into a 1x2 matrix:
                                             Previous iteration is y.
                      #                      Take height of y,
                   i.@                       turn into range
                 =@                          and form array of self-equality.
                                             This results in the identity
                                             matrix with same height as y.
                       ,-                    Concatenate with -y, pad with 0s.
       (    )"1@(        )                   Then do to every row:
        |.,-                                 Concatenate reversal to negation.
' /\'{~                                     Finally index entry-wise into string.

1

JavaScript (ES6), 105 ไบต์

f=n=>n<2?"/\\":" "+f(n-1).split`/`[0].replace(/|/g,"$`$'$'/$`$`\\$'$'$` \n")+f(n-1).replace(/.*/g,"$&$&")

ทำงานโดยการสร้างผลลัพธ์ซ้ำจากเคสพื้นฐานในตำแหน่งที่ถูกต้อง บรรทัดใหม่และช่องว่างภายในยังเพิ่มที่นี่; นี้จะดูแล padding ทั้งหมดยกเว้นพื้นที่ต่อท้ายในแต่ละบรรทัดและพื้นที่ชั้นนำในบรรทัดแรกที่ฉันต้องเพิ่มด้วยตนเอง (ช่องว่างนำหน้าในบรรทัดถัดมามาจากสตริงที่ตรงกัน)/\ทำงานโดยการสร้างผลขึ้นซ้ำจากกรณีฐานครึ่งล่างเป็นเพียงกรณีก่อนหน้าโดยมีการทำซ้ำแต่ละบรรทัด ครึ่งบนนั้นค่อนข้างเล่ห์เหลี่ยมเล็กน้อย ดูเหมือนว่าคุณต้องการที่จะใช้กรณีก่อนหน้านี้และรักษาทั้งสองด้านไว้เท่านั้น แต่คุณต้องกังวลเกี่ยวกับการขยายสายอักขระให้กว้างเป็นสองเท่าของความกว้างดังนั้นฉันจึงใช้เวทมนตร์ Regex แทน ด้วยการใช้ช่องว่างนำหน้าจากเคสก่อนหน้าและแยกทุกจุดฉันสามารถพิจารณาช่องว่างก่อนและหลังจุดนั้นได้ ในแต่ละการจับคู่ช่องว่างก่อนที่จะเพิ่มขึ้น 1 และช่องว่างหลังจากลดลง 1 สิ่งนี้สามารถใช้เพื่อวางตำแหน่ง/และ\


1

ถ่าน 12 ไบต์

FN«→↗⌈X²⊖ι‖M

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

 N              Input as a number
F «             Loop over implicit range
   →            Move right (because mirroring moves the cursor)
         ι      Current index
        ⊖       Decremented
      X²        Power of 2
     ⌈          Ceiling
    ↗           Draw diagonal line
          ‖M    Mirror image

ความยาวบรรทัดคือ 1, 1, 2, 4, 8 ... 2 ^ (N-2) ดังนั้นการคำนวณที่น่าอึดอัดใจ



0

รุ่นที่ 218 ไบต์

@echo off
set/a"n=1<<%1"
set s=set t=
%s%/\
set l=for /l %%i in (2,1,%n%)do call
%l% %s% %%t%% 
%l%:l
:l
echo %t%
set/an-=1,m=n^&n-1
%s%%t: /=/ %
%s%%t:\ = \%
if %m% neq 0 exit/b
%s%%t:/ =/\%
%s%%t: \=/\%

หมายเหตุ: บรรทัด 6 สิ้นสุดในช่องว่าง ทำงานโดยการย้ายกิ่งไม้ไปทางซ้ายและขวาอย่างเหมาะสมในแต่ละครั้งยกเว้นในแถวที่มี 2 nจากจุดสิ้นสุดซึ่งในกรณีนี้กิ่งจะถูกแยกแทน


0

Haxe, 181 ไบต์

function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");

หรือด้วยช่องว่างเสริม:

function g(n):String
  return
    (n -= 2) == -1
    ? "/\\"
    : [ for (y in 0...1 << n)
        [ for (x in 0...4 << n)
          x + y + 1 == 2 << n
          ? "/"
          : x - y == 2 << n
            ? "\\"
            : " "
        ].join("")
      ].concat([ for (y in g(n + 1).split("\n"))
        y + y
      ]).join("\n");

ฉันทำงานไประยะหนึ่งเพื่อแก้ปัญหาที่สร้างอาร์เรย์ของอักขระช่องว่างที่มีขนาดถูกต้องก่อนจากนั้นจึงใส่เส้นทางที่แยกกันไปทางล่างและล่างซ้ำ ๆ แม้ว่ามันจะยังคงอยู่ที่ 230+ ไบต์ วิธีการที่นี่นั้นค่อนข้างใกล้เคียงกับแนวทางของ Haskell ที่ @ Laikoni ฉันไม่สามารถออกไปโดยไม่ได้มี:Stringเพราะ Haxe ไม่ฉลาดพอที่จะระบุว่าประเภทการส่งคืนจะเป็นสตริงเสมอ

นี่เป็นเพียงฟังก์ชั่นต่อไปนี้เป็นโปรแกรมเต็มรูปแบบเพื่อทดสอบ:

class Main {
    public static function main(){
        function g(n):String return(n-=2)==-1?"/\\":[for(y in 0...1<<n)[for(x in 0...4<<n)x+y+1==2<<n?"/":x-y==2<<n?"\\":" "].join("")].concat([for(y in g(n+1).split("\n"))y+y]).join("\n");
        Sys.println(g(Std.parseInt(Sys.args()[0])));
    }
}

ใส่ข้างบนMain.hxรวบรวมhaxe -main Main.hx -neko frac.nและทดสอบด้วยneko frac.n 4(แทนที่4ด้วยลำดับที่ต้องการ)


0

PHP, 188 ไบต์

เวอร์ชั่นออนไลน์

function f($l,$r=0,$m=1){global$a;for(;$i<$l;$i++)$i<$l/2?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m):f($l/2^0,$r+$l/2,2*$m);}f(2**$argv[1]/2);echo join("\n",$a);

ขยาย

function f($l,$r=0,$m=1){
global$a;    
for(;$i<$l;$i++)    
$i<$l/2
    ?$a[$i+$r]=str_repeat(str_pad("/".str_pad("",2*$i)."\\",2*$l," ",2),$m)
    :f($l/2^0,$r+$l/2,2*$m);
}
f(2**$argv[1]/2);
echo join("\n",$a);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.