Menggambar pohon dari sebuah array

24

Dengan kemungkinan array bertumpuk, non-kosong, bilangan bulat positif satu digit (tidak dijamin unik), mengeluarkan representasi ASCII-art sebagai pohon, menggunakan karakter gambar kotak ┌ ┴ ┐ ─ │ ┬ ┼. (Ini disalin dari Kode Halaman 437, tetapi Anda dapat menggunakan representasi yang setara).

Setiap bilangan bulat array harus berupa daun pohon. Elemen-elemen dengan level yang sama jauh di dalam array harus ada di level pohon yang sama. Semua elemen harus dipisahkan oleh spasi yang cukup untuk menjadi berbeda (terserah Anda untuk menentukan seberapa lebar, minimal satu ruang antara).

Sebagai contoh, array yang diberikan [[1, [2]], [3, [4, 5]]], output pohon berikut

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

Untuk susunan [1, 2, 3]pohon bisa terlihat seperti

┌─┼─┐
1 2 3

Tetapi array [[1, 2, 3]]akan terlihat seperti

  │
┌─┼─┐
1 2 3

Sementara array [1, [1, [1, [1]]]]bisa terlihat seperti

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

Sebagai contoh yang lebih rumit, [1, [[[2, 3], 4], 5]]bisa jadi

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

atau beberapa variasi lainnya.


  • Input dan output dapat diberikan dengan metode apa pun yang mudah .
  • Anda dapat mencetaknya ke STDOUT atau mengembalikannya sebagai hasil fungsi.
  • Program lengkap atau fungsi dapat diterima.
  • Berapapun ruang kosong ekstranus dapat diterima, asalkan karakter berbaris dengan tepat.
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.
AdmBorkBork
sumber
[1,[[[2,3],4],5]]bisa menjadi kasus uji yang menarik karena perlu memiliki root buatan memperpanjang sehingga subtree kanan tidak bertabrakan dengan subtree kiri.
Poke
@ Poke Ditambahkan sebagai contoh. Ada beberapa variasi yang mungkin untuk test case itu.
AdmBorkBork
2
Contoh pertama untuk test case itu tidak benar. Itu menunjukkan bahwa s elemen kedua di sebelah 1adalah array dari 3 item: [2,3], 4, dan 5. Tetapi 4 dan 5 tidak berdekatan.
Draco18s
4
Sepertinya [1, [[[2, 3]], [4], 5]]saya.
Neil
Manakah (jika ada) format input alternatif ini yang dapat diterima?
Οurous

Jawaban:

12

Python 3 , 400 393 390 byte

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]

Mengembalikan daftar string dari atas ke bawah.

EDIT 1: Dipotong 7 byte dengan menghindari duplikasi ┴┼(simpanan bersih 2 byte), memotong 0 dari satu string, mengubah cara menggambar karakter dipilih dari ┬┌┐(gunakan <bukan ==), dan mengganti L(z)I terjawab dengane

EDIT 2: -2 bytes terima kasih kepada ovs dan -1 byte terima kasih kepada Kevin Cruijssen

Cobalah online!

Tidak disatukan

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]

Membangun pohon dari daun ke atas, satu lapis pada satu waktu.

Beefster
sumber
2
Saya menambahkan test case ke tautan TIO Anda. Cobalah secara online!
pizzapants184
Jawaban bagus! Anda dapat mempersingkat ini dengan dua byte dengan menetapkan spasi untuk variabel seperti ini:S,*K=' ┴┼│123456789' .
Ovs
1
e==1bisa e<2untuk menyimpan byte (saya tidak berpikir itu bisa menjadi 0, karena tantangan menyatakan input tidak kosong - dan input kosong sudah gagal di max(map(L,z))dalam kasus itu.)
Kevin Cruijssen
3

Bersih , 544 506 byte

Escapes digunakan untuk menghindari UTF-8 yang tidak valid pada SE / TIO tetapi dihitung sebagai satu byte karena mereka benar literal

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

Cobalah online!

Mengambil input dalam format L[I 3, L[I 4, I 5], I 2]..

Menghubungkan pohon-pohon dari bawah ke atas, kiri ke kanan, lalu sesuaikan jarak dari kanan ke kiri.

Prettified, semacam:

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]];
Suram
sumber
3

Arang , 127 123 byte

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

Cobalah online!Tautan adalah untuk mengucapkan versi kode. Penjelasan:

Ubah arah gambar default ke atas karena kami tidak menarik apa pun ke kanan.

≔⟦⟦θ⟧⟧η

Langkah pertama adalah untuk mengkonversi representasi array yang bersarang ke dalam representasi indeks yang merupakan daftar semua entri bersama-sama dengan indeks dari subarrays, misalnya untuk input q=[1, [[[2, 3]], [4], 5]]yang 5adalah q[1][2]dan oleh karena itu daftar yang kita inginkan adalah1, 2 . Kami mulai dengan satu entri untuk memproses yang merupakan daftar yang berisi daftar indeks saat ini (yaitu tidak ada sejauh ini) dan input asli.

Fη«

Ulangi array saat kami memprosesnya. (Arang yang nyaman akan terus beralih ke daftar jika Anda mendorongnya selama iterasi.)

≔⊟ιζ

Dapatkan array selanjutnya untuk diproses.

¿⁼Iζ⪫⟦ζ⟧ω

Apakah ini sebenarnya skalar daripada array?

⊞υ⊞Oιζ

Jika demikian, maka daftar yang kami miliki sebenarnya berada di daftar akhir daftar indeks.

FLζ

Jika tidak, loop setiap elemen dalam array ini ...

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

... dan simpan dengan daftar indeks baru sejauh ini untuk diproses lebih lanjut. Indeks maksimum array juga disimpan yang digunakan untuk huruf besar-kecil elemen terakhir dari array.

Wυ«

Kami sekarang siap untuk mengulang daftar daftar indeks. Namun, daftar ini tidak dalam urutan leksikografis, jadi kami tidak dapat mengulanginya secara langsung.

≔⌊υι

Temukan elemen berikutnya dalam urutan leksikografis.

≔Φυ¬⁼κιυ

Hapus dari daftar.

J±⊗Lυ⊘⊖Lι

Lompat ke posisi skalar di output. Kita dapat menghitung ini mengingat kita dapat terus menghitung jumlah skalar yang kita hasilkan dan kita juga tahu jumlah entri dalam daftar indeksnya.

I⊟ι

Sebenarnya cetak skalar.

Wι«

Ulangi entri dalam daftar indeks. Sekali lagi, ini bukan iterasi sederhana, karena entri datang berpasangan, dan kita juga harus bisa keluar dari loop.

≔⊟ιζ

Ekstrak indeks berikutnya dari daftar.

¿ζ«

Jika ini bukan elemen pertama dalam daftar ...

←§┐┬‹ζ⊟ι

... lalu cetak atau tergantung apakah ini adalah elemen terakhir dalam daftar ...

W⁼KKψ←─

... dan cukup cetak untuk mengisi entri sebelumnya di level ini ...

≔⁰ι»

... dan hapus variabel untuk keluar dari loop karena kita sudah selesai di sini.

¿⊟ι┌¶┴

Kalau tidak, jika ini adalah (elemen pertama) daftar beberapa elemen kemudian cetak ┌┴, meninggalkan kursor di atas untuk berurusan dengan induk level ini.

¦│

Kalau tidak, jika ini adalah daftar 1-elemen maka cukup cetak a dan naikkan garis untuk berurusan dengan induk level ini.

Neil
sumber