Parser Tag Sederhana

9

Ini adalah model pengurai HTML yang pemaaf. Alih-alih mem-parsing HTML dan mengekstraksi atribut, dalam kode golf ini, parser tag akan menjadi sederhana.

Tulis fungsi yang mem-parsing struktur tag dan mengembalikan formulir yang disisipkan. Tag pembuka terdiri dari satu huruf kecil, dan tag penutup terdiri dari satu huruf besar. Misalnya, aAbaABmem-parsing ke dalam (a)(b(a)), atau dalam HTML <a></a><b><a></a></b>,. Tentu saja, tag dapat disandingkan dan bersarang.

Tag tertutup "Prematur" harus ditangani. Misalnya, di abcA, Atutup bagian terluar a, jadi diuraikan (a(b(c))).

Tag penutup ekstra hanya diabaikan: aABdiurai menjadi (a).

Tag yang tumpang tindih TIDAK ditangani. Misalnya, abABmem-parsing ke dalam (a(b)), tidak (a(b))(b), oleh aturan sebelumnya dari tag penutup tambahan ( abAB-> abA( (a(b))) + B(ekstra)).

Dengan asumsi tidak ada spasi putih dan karakter ilegal lainnya dalam input.

Anda tidak diizinkan menggunakan perpustakaan apa pun.

Berikut ini adalah implementasi referensi dan daftar kasus uji:

#!/usr/bin/python

def pars(inpu):
  outp = ""
  stac = []
  i = 0
  for x in inpu:
    lowr = x.lower()
    if x == lowr:
      stac.append(x)
      outp += "(" + x
      i = i + 1
    else:
      while len(stac) > 1 and stac[len(stac) - 1] != lowr:
        outp += ")"
        stac.pop()
        i = i - 1
      if len(stac) > 0:
        outp += ")"
        stac.pop()
        i = i - 1
  outp += ")" * i
  return outp

tests = [
  ("aAaAbB", "(a)(a)(b)"),
  ("abBcdDCA", "(a(b)(c(d)))"),
  ("bisSsIB", "(b(i(s)(s)))"),
  ("aAabc", "(a)(a(b(c)))"),
  ("abcdDA", "(a(b(c(d))))"),
  ("abcAaA", "(a(b(c)))(a)"),
  ("acAC", "(a(c))"),
  ("ABCDEFG", ""),
  ("AbcBCabA", "(b(c))(a(b))")
]

for case, expe in tests:
  actu = pars(case)
  print "%s: C: [%s] E: [%s] A: [%s]" % (["FAIL", "PASS"][expe == actu], case, expe, actu)

Kode terpendek menang.

Ming-Tang
sumber
seperti golf kode lainnya, perpustakaan standar diizinkan
Ming-Tang
tidak ada batasan panjang atau tingkat sarang
Ming-Tang
4
Anda harus menambahkan test case untuk input yang mengarah dengan tag penutup, seperti AbcBCabA(harus diurai sebagai (b(c))(a(b)). Kode saya bisa lebih pendek kecuali untuk case ini.
MtnViewMark

Jawaban:

1

Golfscript, 54 karakter

{[]:|\{.96>{.|+:|;40\}{32+|?).')'*\|>:|;}if}%|,')'*}:$

Tes

;["aAaAbB" "abBcdDCA" "bisSsIB" "aAabc" "abcdDA" "abcAaA" "acAC" "aAB" "abAB" "AbcBCabA"]{.' '\$n}%

aAaAbBaAaAbB (a)(a)(b)
abBcdDCA (a(b)(c(d)))
bisSsIB (b(i(s)(s)))
aAabc (a)(a(b(c)))
abcdDA (a(b(c(d))))
abcAaA (a(b(c)))(a)
acAC (a(c))
aAB (a)
abAB (a(b))
AbcBCabA (b(c))(a(b))
KAMU
sumber
6

Haskell, 111 karakter

s@(d:z)§c|c>'^'=toEnum(fromEnum c-32):s++'(':[c]|d<'='=s|d==c=z++")"|1<3=(z++")")§c
p=tail.foldl(§)"$".(++"$")

Ini golf yang bagus untuk Haskell. Fitur menyenangkan: Tumpukan dan akumulasi keluaran disimpan dalam string yang sama!

Kasus uji:

> runTests 
Pass: aAbaAB parsed correctly as (a)(b(a))
Pass: abcA parsed correctly as (a(b(c)))
Pass: aAB parsed correctly as (a)
Pass: abAB parsed correctly as (a(b))
Pass: aAaAbB parsed correctly as (a)(a)(b)
Pass: abBcdDCA parsed correctly as (a(b)(c(d)))
Pass: bisSsIB parsed correctly as (b(i(s)(s)))
Pass: aAabc parsed correctly as (a)(a(b(c)))
Pass: abcdDA parsed correctly as (a(b(c(d))))
Pass: abcAaA parsed correctly as (a(b(c)))(a)
Pass: acAC parsed correctly as (a(c))
Pass: AbcBCabA parsed correctly as (b(c))(a(b))

  • Sunting: (113 → 111) menggunakan @pola seperti yang disarankan oleh FUZxxl
MtnViewMark
sumber
Menggunakan @ -pattern untuk d: z mungkin menghemat dua karakter.
FUZxxl
4

Kode Mesin Z80 untuk TI-83 +, 41 byte

Ini adalah implementasi dalam kode mesin heksadesimal untuk cpu z80 yang berjalan pada TI-83 +.

11XXXX131AFE61380F6FE53E28CD9DB47DCD9DB4188EE1BDC03E29CD9DB4189BEF4504E5214CE1C9

XXXX (3 - 6 inklusif) adalah alamat 16-bit dari string yang Anda parsing, minus 1 byte.

Disandikan dalam Z80-ASCII:

¹XX≤¯•⟙8𝑭o↥>(ˣïÑ}ˣïÑ≠á↑γ∊>)ˣïÑ≠Ì⬆︎E𝑤↥!₄L↑Φ

(Perkiraan, karena kalkulator TI memiliki karakter mereka sendiri.)

CATATAN BAHWA AsmPrgmTIDAK TERMASUK DI ATAS

Élektra
sumber
2

Windows PowerShell, 142 146 147 152 156 169

{$s=''
-join([char[]]"$args "|%{if(90-ge$_){')'*(($x=$s.indexOf("$_".ToLower())+1)+$s.Length*!$x)
$s=$s.substring($x)}else{"($_"
$s="$_$s"}})}

Beberapa hal yang perlu diperhatikan: Ini hanya blok skrip. Itu dapat ditugaskan ke variabel atau diberi nama fungsi, jika perlu. Anda juga dapat menjalankannya dengan meletakkan .atau &di depannya dan argumen di akhir. Menggunakan ruang terakhir untuk mengakhiri tag yang tidak tertutup.

Lewati semua tes. Skrip uji:

$tests = ("aAaAbB","(a)(a)(b)"),("abBcdDCA","(a(b)(c(d)))"),("bisSsIB","(b(i(s)(s)))"),("aAabc","(a)(a(b(c)))"),("abcdDA","(a(b(c(d))))"),("abcAaA", "(a(b(c)))(a)"),("acAC","(a(c))")
"function f " + ((gc ./tags.ps1)-join"`n") | iex
$tests | %{
    $result = f $_[0]
    ("FAIL: $($_[0]):$($_[1]) - $result", 'PASS')[$result -ceq $_[1]]
}
Joey
sumber
2

Python - 114 113 153 153 192 174 159 karakter

from sys import *
s="";c=a=argv[1]
for f in a:
 o=c.find;p=f.lower
 if '@'<f<'\\':
\td=o(f)-o(p())
\ts+=")"*d
\tc=(c[:o(p())]+c[o(f)+1:])
 else:s+=("("+f)
print s

Menyalahgunakan parser lekukan python untuk menggunakan satu spasi untuk satu tab penuh, lima untuk dua tab.

Sunting 1 - menyimpan ruang yang tidak dibutuhkan dalam fungsi rentang ()

Sunting 2 - diperbaiki untuk menangani tata bahasa parse yang tidak tepat, tag yang tidak terminasi.

Sunting 3 - memperbaiki bug di mana parse "salah" dapat dihasilkan oleh ambiguitas di pohon tag. Menerapkan strategi berbasis tumpukan, bukan penghitung.

Sunting 4 - berganti nama s.find ke o untuk mencegah penyimpanan karakter yang digunakan untuk memanggilnya berulang kali. melakukan hal yang sama untuk f.lower.

Sunting 5 - menambahkan hack ruang / tab, menyimpan tiga karakter.

Sunting 6 - membuang lingkaran demi ")" * d.

arrdem
sumber
1
bukannya ord(f)...Anda dapat menggunakan '@'<f<'\\'Jika Anda tidak perlu untuk memeriksa '\\'Anda dapat menggunakan ']'bukannya
gnibbler
1
Anda dapat menggunakan satu tab alih-alih 5 spasi. Markup kode SO tidak dapat menanganinya :(. Dalam kasus Anda, cukup letakkan saja baris baru dan spasi secara bersamaan. Misalnya if ...:s+=")";c-=1danelse:s+="("+f;c+=1
gnibbler
1
for i in range(d):s+=")"dapat ditulis ulang sebagai s+=")"*d. Dan Anda memiliki 174 karakter.
cemper93
@emper - poin bagus itu. Saya melakukan "_" * 80 sepanjang hari dan melupakannya saat bermain golf .... Juga, terima kasih kepada @gnibbler untuk sarannya!
arrdem
Sebenarnya, maksud saya Anda memiliki 174 karakter sebelumnya . Jadi, Anda berada di 159 sekarang.
cemper93