การวาดต้นไม้จากอาร์เรย์


24

ได้รับอาจจะซ้อนกันอาร์เรย์ที่ไม่ว่างเปล่าของจำนวนเต็มบวกหลักเดียว (ไม่รับประกันไม่ซ้ำกัน) เอาท์พุทเป็นตัวแทน ASCII ┌ ┴ ┐ ─ │ ┬ ┼ศิลปะเหมือนต้นไม้โดยใช้ตัวอักษรกล่องวาดภาพ (สิ่งเหล่านี้ถูกคัดลอกมาจากรหัสหน้า 437 แต่คุณสามารถใช้การแทนที่เทียบเท่ากันได้)

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

ตัวอย่างเช่นอาร์เรย์ที่กำหนด[[1, [2]], [3, [4, 5]]]เอาท์พุทต้นไม้ต่อไปนี้

 ┌─┴─┐
┌┴┐ ┌┴─┐
1 │ 3 ┌┴┐
  2   4 5

สำหรับอาร์เรย์[1, 2, 3]ต้นไม้อาจมีลักษณะเช่น

┌─┼─┐
1 2 3

แต่อาร์เรย์[[1, 2, 3]]จะดูเหมือน

  │
┌─┼─┐
1 2 3

ในขณะที่อาร์เรย์[1, [1, [1, [1]]]]อาจมีลักษณะเช่น

 ┌─┴┐
 1 ┌┴─┐
   1 ┌┴┐
     1 │
       1

เป็นตัวอย่างที่ซับซ้อนมากขึ้น[1, [[[2, 3], 4], 5]]อาจเป็น

┌┴───┐
1  ┌─┴┐
 ┌─┴┐ 5
┌┴┐ 4
2 3

หรืออีกหลายรูปแบบ


  • เข้าและส่งออกจะได้รับโดยวิธีการที่สะดวกใด
  • คุณสามารถพิมพ์ไปที่ STDOUT หรือส่งคืนเป็นผลลัพธ์ของฟังก์ชัน
  • ยอมรับได้ทั้งโปรแกรมหรือฟังก์ชั่น
  • สามารถยอมรับช่องว่างที่ไม่เกี่ยวข้องใด ๆ ได้ตราบใดที่อักขระมีการจัดเรียงอย่างเหมาะสม
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • นี่คือเพื่อให้ใช้กฎการตีกอล์ฟตามปกติทั้งหมดและรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ

[1,[[[2,3],4],5]]อาจเป็นกรณีทดสอบที่น่าสนใจเนื่องจากต้องมีการขยายรากเทียมเพื่อทรีย่อยที่เหมาะสมจะไม่ชนกับทรีย่อยด้านซ้าย
สะกิด

@Poke เพิ่มเป็นตัวอย่าง มีรูปแบบที่เป็นไปได้หลายอย่างสำหรับกรณีทดสอบดังกล่าว
AdmBorkBork

2
ตัวอย่างแรกสำหรับกรณีทดสอบนั้นไม่ถูกต้อง นั่นแสดงให้เห็นว่า s องค์ประกอบที่สองถัดจาก1เป็นอาร์เรย์จาก 3 รายการ: [2,3], และ4 5แต่ 4 และ 5 ไม่ได้อยู่ติดกัน
Draco18s

4
ที่ดูเหมือน[1, [[[2, 3]], [4], 5]]กับฉัน
Neil

ซึ่ง (ถ้ามี) ของเหล่านี้รูปแบบการป้อนทางเลือกที่จะเป็นที่ยอมรับ?
Οurous

คำตอบ:


12

Python 3 , 400 393 390 bytes

L=len
S,*K=' ┴┼│123456789'
def T(x):
 try:return[str(x+0)]
 except:
  z=[*map(T,x)];q=max(map(L,z))
  for p in z:p+=[S*L(p[0])]*(q-L(p))
  b=[S.join(a)for a in zip(*z)];t=b[0];l=L(t);s=0;e=L(z);r=[S]*l
  if e<2:return['│'.center(l),*b]
  for i in range(l):
   if t[i]in K:s+=1;r[i]='┬┌┐'[(s<e)-(s>1)]
   elif 0<s<e:r[i]='─'
  c=l//2;r[c]=K[r[c]=='┬'];return[''.join(r),*b]

ส่งคืนรายการสตริงจากบนลงล่าง

แก้ไข 1: ตัดแต่ง 7 ไบต์โดยหลีกเลี่ยงการทำซ้ำ┴┼(บันทึกสุทธิ 2 ไบต์) ตัด 0 จากสตริงหนึ่งเปลี่ยนวิธีการเลือกอักขระการวาดจาก┬┌┐(ใช้<แทน==) และแทนที่L(z)ฉันพลาดด้วยe

แก้ไข 2: -2 ไบต์ขอบคุณ ovs และ -1 ไบต์ขอบคุณ Kevin Cruijssen

ลองออนไลน์!

Ungolfed

def layer(item):
    if isinstance(item, int):
        return [str(item)]
    else:
        subs = [layer(sub) for sub in item]
        longest = max(map(len, subs))
        for sub in subs:
            sub += [' ' * len(sub[0])] * (longest - len(sub))
        below = [' '.join(l) for l in zip(*subs)]
        top = below[0]
        l = len(top)
        if len(subs) == 1:
            return ['│'.center(l), *below]
        seen = 0
        expected = len(subs)
        builder = [' '] * l
        for i in range(l):
            c = top[i]
            if c in '┴┼│123456789':
                seen += 1
                if seen == 1:
                    builder[i] = '┌'
                elif seen == expected:
                    builder[i] = '┐'
                else:
                    builder[i] = '┬'
            elif 0 < seen < expected:
                builder[i] = '─'
        center = l // 2
        if builder[center] == '┬':
            builder[center] = '┼'
        else:
            builder[center] = '┴'
        return [''.join(builder), *below]

สร้างต้นไม้จากใบขึ้นหนึ่งชั้นในเวลา


2
ฉันเพิ่มกรณีทดสอบลงในลิงก์ TIO ของคุณลองออนไลน์!
pizzapants184

คำตอบที่ดี! S,*K=' ┴┼│123456789'คุณสามารถลดระยะนี้โดยไบต์ที่สองโดยการกำหนดพื้นที่ที่จะตัวแปรเช่นนี้:
ovs

1
e==1สามารถe<2บันทึกไบต์ได้ (ฉันไม่คิดว่าจะเป็น 0 ได้เนื่องจากความท้าทายระบุว่าอินพุตไม่ว่าง - และอินพุตว่างจะล้มเหลวmax(map(L,z))ในกรณีนี้อยู่แล้ว)
Kevin Cruijssen

3

ทำความสะอาด , 544 506 bytes

การหลบหนีถูกใช้เพื่อหลีกเลี่ยง UTF-8 ที่ไม่ถูกต้องใน SE / TIO แต่นับเป็นหนึ่งไบต์เนื่องจากเป็นตัวอักษรที่ถูกต้อง

import StdEnv,Data.List;::T=I Int|L[T];$l#m= @l#k=map maxList(transpose m)=flatlines[[last[' ':[(\_|v<0|w<[j]|q>hd w|q<last w|any((==)q)w|q==j='\305'='\302'|q==j='\301'='\304'='\277'='\332'='\263'=toChar v+'0')0\\[v,r,j:w]<-m|r/2==p&&q>=hd w&&q<=last w]]\\q<-[0..k!!3]]\\p<-[0..k!!1]];@(L l)#p=twice(\p=[[v,r+1:[e+sum([2\\[v:_]<-i|0<=v]++zipWith(\c j=j!!2-c!!3)t(takeWhile(\[z:_]=v+z< -1)(tl t)))-x!!1\\e<-x]]\\i<-inits p&t<-tails p&[v,r:x]<-p])(concatMap@l)#g=[g\\[_,2,g:_]<-p]=[[-1,0,(hd g+last g)/2:g]:p];@(I i)=[[i,0,0,0]];

ลองออนไลน์!

ใช้อินพุตในรูปแบบ L[I 3, L[I 4, I 5], I 2]..

เชื่อมต่อต้นไม้จากด้านล่างขึ้นจากซ้ายไปขวาจากนั้นปรับระยะทางจากขวาไปซ้าย

การเรียงลำดับของ:

import StdEnv, Data.List;
:: T = I Int | L [T];
$ l
    #m = @l
    #k = map maxList (transpose m)
    = flatlines [
        [
            last[
                ' ':
                [
                    if(v < 0)
                        if(w < [j])
                            if(q > hd w)
                                if(q < last w)
                                    if(any ((==) q) w)
                                        (
                                            if(q == j)
                                                '\305'
                                                '\302'
                                        )(
                                            if(q == j)
                                                '\301'
                                                '\304'
                                        )
                                    '\277'
                                '\332'
                            '\263'
                        (toChar v + '0')
                    \\ [v, r, j: w] <- m
                    | r/2 == p && q >= hd w && q <= last w
                ]
            ]
            \\ q <- [0..k!!3]
        ]
        \\p<-[0..k!!1]
    ];
@ (L l)
    #p = twice
        ( \p
            = [
                [
                    v, r + 1:
                    map
                        (
                            (+)
                            (
                                sum [2 \\ [v: _] <- i| 0 <= v]
                                + sum (
                                    zipWith
                                        (
                                            \[_, _, _, c: _] [_, _, j: _] = j - c
                                        )
                                        t
                                        (
                                            takeWhile (\[v: _] = v < 0) (tl t)
                                        )
                                ) * (1 - sign (v + 1))
                                - x!!1
                            )
                        )
                        x
                ]
            \\ i <- inits p
            &  t <- tails p
            &  [v, r: x] <- p
            ]
        )
        (concatMap @ l)
    #g = [g \\ [_, 2, g: _] <- p]
    =[[-1, 0, (hd g + last g)/2: g]: p];
@ (I i) = [[i, 0, 0, 0]];

3

ถ่าน , 127 123 ไบต์

↶≔⟦⟦θ⟧⟧ηFη«≔⊟ιζ¿⁼Iζ⪫⟦ζ⟧ω⊞υ⊞OιζFLζ⊞η⁺ι⟦⊖Lζκ§ζκ⟧»Wυ«≔⌊υι≔Φυ¬⁼κιυJ±⊗Lυ⊘⊖LιI⊟ιWι«≔⊟ιζ¿ζ«←§┐┬‹ζ⊟ιW⁼KKψ←─≔⁰ι»¿⊟ι┌¶┴¦│

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

เปลี่ยนทิศทางการวาดเริ่มต้นเป็นขึ้นเนื่องจากเราไม่ได้วาดอะไรไปทางขวา

≔⟦⟦θ⟧⟧η

ขั้นตอนแรกคือการแปลงแสดงอาร์เรย์ที่ซ้อนกันเป็นตัวแทนดัชนีซึ่งเป็นรายการของรายการทั้งหมดเข้าด้วยกันกับดัชนีของ subarrays ที่เป็นเช่นสำหรับการป้อนข้อมูลถูกและดังนั้นจึงรายการที่เราต้องการคือ เราเริ่มต้นด้วยรายการเดียวในการประมวลผลซึ่งเป็นรายการที่มีรายการของดัชนีปัจจุบัน (เช่นไม่มีจนถึง) และอินพุตต้นฉบับq=[1, [[[2, 3]], [4], 5]]5q[1][2]1, 2

Fη«

วนรอบอาร์เรย์ในขณะที่เราประมวลผล (ถ่านอย่างสะดวกสบายจะยังคงวนซ้ำในรายการถ้าคุณกดในระหว่างการทำซ้ำ)

≔⊟ιζ

รับอาเรย์ถัดไปเพื่อดำเนินการ

¿⁼Iζ⪫⟦ζ⟧ω

นี่คือเซนต์คิตส์และเนวิสมากกว่าอาร์เรย์หรือไม่

⊞υ⊞Oιζ

ถ้าเป็นเช่นนั้นรายการที่เรามีอยู่ในรายการสุดท้ายของดัชนี

FLζ

มิฉะนั้นให้วนซ้ำแต่ละองค์ประกอบในอาร์เรย์นี้ ...

⊞η⁺ι⟦⊖Lζκ§ζκ⟧»

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

Wυ«

ตอนนี้เราพร้อมที่จะวนรอบรายการรายการดัชนี อย่างไรก็ตามรายการไม่ได้อยู่ในลำดับพจนานุกรมดังนั้นเราจึงไม่สามารถทำซ้ำได้โดยตรง

≔⌊υι

ค้นหาองค์ประกอบถัดไปตามลำดับพจนานุกรม

≔Φυ¬⁼κιυ

ลบออกจากรายการ

J±⊗Lυ⊘⊖Lι

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

I⊟ι

พิมพ์สเกลาร์จริง ๆ

Wι«

วนซ้ำรายการในรายการดัชนี อีกครั้งนี่ไม่ใช่การทำซ้ำง่าย ๆ เพราะรายการมีคู่กันและเราต้องแยกวงออกมาด้วย

≔⊟ιζ

แยกดัชนีถัดไปออกจากรายการ

¿ζ«

หากนี่ไม่ใช่องค์ประกอบแรกในรายการ ...

←§┐┬‹ζ⊟ι

... จากนั้นพิมพ์หรือขึ้นอยู่กับว่านี่เป็นองค์ประกอบสุดท้ายในรายการ ...

W⁼KKψ←─

... และพิมพ์พอที่จะเติมจนถึงรายการก่อนหน้าในระดับนี้ ...

≔⁰ι»

... และล้างตัวแปรเพื่อแยกออกจากลูปตั้งแต่เราทำที่นี่

¿⊟ι┌¶┴

มิฉะนั้นถ้านี่คือ (องค์ประกอบแรกของ) รายการหลายองค์ประกอบจากนั้นพิมพ์ให้┌┴ปล่อยเคอร์เซอร์ไว้เหนือเพื่อจัดการกับพาเรนต์ของระดับนี้

¦│

มิฉะนั้นถ้านี่เป็นรายการ 1 องค์ประกอบเพียงแค่พิมพ์และเลื่อนขึ้นบรรทัดเพื่อจัดการกับพาเรนต์ของระดับนี้

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