Temukan simpul terdalam pohon biner

9

Tulis program yang menggunakan pohon biner sebagai input, dan output simpul terdalam dan kedalamannya. Jika ada dasi, cetak semua simpul yang terlibat serta dalamnya. Setiap node direpresentasikan sebagai:

T(x,x)

T(x)

T

di mana Tadalah pengidentifikasi satu atau lebih karakter alfanumerik dan masing-masing xadalah simpul lain.

Berikut definisi sederhana dari pohon biner:

  • Di kepala pohon biner adalah sebuah simpul.
  • Sebuah simpul di pohon biner memiliki paling banyak dua anak.

Sebagai contoh, input A(B(C,D(E)))(di bawah) akan menampilkan 3:E.

Pohon 1

Sementara pohon berikut ini adalah ikatan tiga arah antara 5, 11, dan 4, dan kedalamannya juga 3 (mulai dari 0):

Input 2(7(2,6(5,11)),5(9(4)))(di bawah) akan menampilkan 3:5,11,4.

Pohon 2

Ini adalah kode golf, jadi kode terpendek yang diukur dalam byte menang.

Jwosty
sumber
@ close-voter: apa yang tidak jelas tentang Anda?
Jwosty
3
Mungkin fakta bahwa tidak ada spesifikasi input atau output, atau uji kasus untuk input dan output tersebut.
Gagang Pintu
Mencoba memperbaikinya tetapi telepon saya menyebalkan ...: P lebih baik demikian.
Jwosty
3
Bukankah seharusnya pohon pertama adalah A (B (C, D (E))?
bakerg
1
@bakerg benar, kesalahan saya. Tetap.
Jwosty

Jawaban:

6

CJam, 49 47

0q')/{'(/):U;,+:TW>{T:W];}*TW={U]',*}*T(}/;W':@

 

0                 " Push 0 ";
q                 " Read the whole input ";
')/               " Split the input by ')' ";
{                 " For each item ";
  '(/             " Split by '(' ";
  )               " Extract the last item of the array ";
  :U;             " Assign the result to U, and discard it ";
  ,               " Get the array length ";
  +               " Add the top two items of the stack, which are the array length and the number initialized to 0 ";
  :T              " Assign the result to T ";
  W>{             " If T>W, while W is always initialized to -1 ";
    T:W];         " Set T to W, and empty the stack ";
  }*
  TW={            " If T==W ";
    U]',*         " Push U and add a ',' between everything in the stack, if there were more than one ";
  }*
  T(              " Push T and decrease by one ";
}/
;                 " Discard the top item, which should be now -1 ";
W                 " Push W ";
':                " Push ':' ";
@                 " Rotate the 3rd item to the top ";
jimmy23013
sumber
Saya telah membuat sedikit modifikasi pada format output untuk membuatnya konsisten dan kurang ambigu, tetapi seharusnya tidak terlalu merepotkan.
Jwosty
@Jwosty Seharusnya tidak, jika ini bukan kode-golf.
jimmy23013
Nah, ini adalah kode-golf ... Tapi bagaimanapun, baik pengajuan :)
Jwosty
Bisakah Anda jelaskan bagaimana cara kerjanya?
Jerry Jeremiah
@JerryJeremiah Diedit.
jimmy23013
5

Haskell, 186 byte

p@(n,s)%(c:z)=maybe((n,s++[c])%z)(\i->p:(n+i,"")%z)$lookup c$zip"),("[-1..1];p%_=[p]
(n,w)&(i,s)|i>n=(i,show i++':':s)|i==n=(n,w++',':s);p&_=p
main=interact$snd.foldl(&)(0,"").((0,"")%)

Program lengkap, aktifkan tree stdin, menghasilkan format output khusus pada stdout:

& echo '2(7(2,6(5,11)),5(9(4)))' | runhaskell 32557-Deepest.hs 
3:5,11,4

& echo 'A(B(C,D(E)))' | runhaskell 32557-Deepest.hs 
3:E

Panduan untuk kode golf'd (menambahkan nama yang lebih baik, ketik tanda tangan, komentar, dan beberapa sub-ekspresi ditarik keluar dan dinamai - tetapi sebaliknya kode yang sama; versi yang ungolf'd tidak akan mengacaukan membobol node dengan penomoran, atau menemukan yang terdalam dengan format output.) :

type Label = String         -- the label on a node
type Node = (Int, Label)    -- the depth of a node, and its label

-- | Break a string into nodes, counting the depth as we go
number :: Node -> String -> [Node]
number node@(n, label) (c:cs) =
    maybe addCharToNode startNewNode $ lookup c adjustTable
  where
    addCharToNode = number (n, label ++ [c]) cs
        -- ^ append current character onto label, and keep numbering rest

    startNewNode adjust = node : number (n + adjust, "") cs
        -- ^ return current node, and the number the rest, adjusting the depth

    adjustTable = zip "),(" [-1..1]
        -- ^ map characters that end node labels onto depth adjustments
        -- Equivalent to [ (')',-1), (',',0), ('(',1) ]

number node _ = [node]      -- default case when there is no more input

-- | Accumulate into the set of deepest nodes, building the formatted output
deepest :: (Int, String) -> Node -> (Int, String)
deepest (m, output) (n, label)
    | n > m     = (n, show n ++ ':' : label)    -- n is deeper tham what we have
    | n == m    = (m, output ++ ',' : label)    -- n is as deep, so add on label
deepest best _ = best                           -- otherwise, not as deep

main' :: IO ()
main' = interact $ getOutput . findDeepest . numberNodes
  where
    numberNodes :: String -> [Node]
    numberNodes = number (0, "")

    findDeepest :: [Node] -> (Int, String)
    findDeepest = foldl deepest (0, "")

    getOutput :: (Int, String) -> String
    getOutput = snd
MtnViewMark
sumber
1
Kode itu membuatku takut.
seequ
Kode penjelas yang diperluas ditambahkan! Biarkan teror membuatmu lebih kuat !!
MtnViewMark
Anda berhak mendapatkan +1 untuk itu.
seequ
Ya Tuhan, dan saya berjuang dengan daftar: P
Artur Trapp
4

GolfScript (75 karakter)

Tidak terlalu kompetitif, tetapi cukup bengkok sehingga memiliki minat:

{.48<{"'^"\39}*}%','-)](+0.{;.@.@>-\}:^;@:Z~{2$2$={@@.}*;}:^;Z~\-])':'@','*

Kode ini memiliki tiga fase. Pertama, kami memproses ulang string input:

# In regex terms, this is s/([ -\/])/'^\1'/g
{.48<{"'^"\39}*}%
# Remove all commas
','-
# Rotate the ' which was added after the closing ) to the start
)](+

Kami telah mengubah misalnya A(B(C,D(E)))menjadi 'A'^('B'^('C'^'D'^('E'^)''^)''^). Jika kita menetapkan blok yang cocok untuk ^kita dapat melakukan pemrosesan yang berguna dengan menggunakan ~untuk mengevaluasi string.

Kedua, kami menemukan kedalaman maksimum:

0.
# The block we assign to ^ assumes that the stack is
#   max-depth current-depth string
# It discards the string and updates max-depth
{;.@.@>-\}:^;
@:Z~

Akhirnya kami memilih node terdalam dan membangun output:

# The block we assign to ^ assumes that the stack is
#   max-depth current-depth string
# If max-depth == current-depth it pushes the string under them on the stack
# Otherwise it discards the string
{2$2$={@@.}*;}:^;
# Eval
Z~
# The stack now contains
#   value1 ... valuen max-depth 0
# Get a positive value for the depth, collect everything into an array, and pop the depth
\-])
# Final rearranging for the desired output
':'@','*
Peter Taylor
sumber
1

Perl 5 - 85

Silakan mengedit posting ini untuk memperbaiki jumlah karakter. Saya menggunakan sayfitur, tetapi saya tidak tahu tentang flag untuk membuatnya berjalan dengan benar tanpa menyatakan use 5.010;.

$_=$t=<>,$i=0;$t=$_,$i++while s/\w+(\((?R)(,(?R))?\))?/$1/g,/\w/;@x=$t=~/\w+/gs;say"$i:@x"

Demo di ideone

Output dipisahkan oleh ruang alih-alih dipisahkan oleh koma.

Kode hanya menggunakan regex rekursif untuk menghapus akar pohon di hutan, sampai tidak mungkin untuk melakukannya. Kemudian string sebelum yang terakhir akan berisi semua node daun pada level terdalam.

Sampel dijalankan

2
0:2

2(3(4(5)),6(7))
3:5

2(7(2,6(5,11)),5(9(4)))
3:5 11 4

1(2(3(4,5),6(7,8)),9(10(11,12),13(14,15)))
3:4 5 7 8 11 12 14 15
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
1

VB.net

Function FindDeepest(t$) As String
  Dim f As New List(Of String)
  Dim m = 0
  Dim d = 0
  Dim x = ""
  For Each c In t
    Select Case c
      Case ","
        If d = m Then f.Add(x)
        x = ""
      Case "("
        d += 1
        If d > m Then f.Clear() :
        m = d
        x = ""
      Case ")"
        If d = m Then f.Add(x) : x = ""
        d -= 1
      Case Else
        x += c
    End Select
  Next
  Return m & ":" & String.Join(",", f)
End Function

Asumsi: Nilai Node tidak dapat berisi ,, (,)

Adam Speight
sumber
1
Ini sepertinya tidak golf sama sekali. Tidak bisakah Anda menghapus sebagian besar spasi putih itu (saya tidak tahu VB)?
seequ
Tergantung beberapa spasi putih signifikan.
Adam Speight
1

Javascript (E6) 120

Versi berulang

m=d=0,n=[''];
prompt().split(/,|(\(|\))/).map(e=>e&&(e=='('?m<++d&&(n[m=d]=''):e==')'?d--:n[d]+=' '+e));
alert(m+':'+n[m])

Tidak disatukan dan diuji

F= a=> (
    m=d=0,n=[''],
    a.split(/,|(\(|\))/)
    .map(e=>e && (e=='(' ? m < ++d && (n[m=d]='') : e==')' ? d-- : n[d]+=' '+e)),
    m+':'+n[m]
)

Tes di konsol Firefox:

['A', '2(7(2,6(5,11)),5(9(4)))', 'A(B(C,D(E)))']
.map(x => x + ' --> ' + F(x)).join('\n')

Keluaran

"A -> 0: A

2 (7 (2,6 (5,11)), 5 (9 (4))) -> 3: 5 11 4

A (B (C, D (E))) -> 3: E "

edc65
sumber