Basit Etiket Ayrıştırıcı


9

Bu, affedici bir HTML ayrıştırıcısının bir modelidir. HTML'yi ayrıştırmak ve öznitelikleri ayıklamak yerine, bu kod golfünde, etiket ayrıştırıcı basit olacaktır.

Bir etiket yapısını ayrıştıran ve parantez içindeki formunu döndüren bir işlev yazın. Açılış etiketi bir küçük harf ve kapanış etiketi bir büyük harf içerir. Örneğin, HTML'de veya HTML'de aAbaABayrışır . Tabii ki, etiketler yan yana ve yuvada olabilir.(a)(b(a))<a></a><b><a></a></b>

"Zamanından önce" kapalı etiketler kullanılmalıdır. Örneğin, içinde abcA, Aen dıştaki kapanır a, bu yüzden içine ayrılır (a(b(c))).

Ekstra kapatma etiketleri dikkate alınmaz: aABiçine ayrılır (a).

Çakışan etiketler KULLANILMAZ. Örneğin, abABiçine ayrıştırır (a(b)), değil (a(b))(b), önceki ekstra kapanış etiketleri üstünlüğü ile ( abAB-> abA( (a(b))) + B(ekstra)).

Girdide boşluk veya diğer geçersiz karakterler olduğu varsayılır.

Herhangi bir kütüphane kullanma izniniz yok.

İşte bir referans uygulaması ve test senaryolarının bir listesi:

#!/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)

En kısa kod kazanır.


diğer kod golfleri gibi, standart kütüphaneye izin verilir
Ming-Tang

uzunluk ve yuvalama seviyesi konusunda sınır yoktur
Ming-Tang 9:11

4
Kapanış etiketi içeren giriş için bir test AbcBCabA(b(c))(a(b))
senaryosu eklemelisiniz

Yanıtlar:


1

Golfscript, 54 karakter

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

Testler

;["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))

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(§)"$".(++"$")

Bu Haskell için oldukça golf. Eğlenceli özellik: Yığın ve biriken çıktı aynı dizede tutulur!

Test senaryoları:

> 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))

  • Düzenleme: (113 → 111) @FUZxxl tarafından önerildiği gibi bir desen kullandı

D: z için @-deseninin kullanılması iki karakter kaydedebilir.
FUZxxl

4

TI-83 +, 41 bayt için Z80 Makine Kodu

Bu, TI-83 + üzerinde çalışan bir z80 işlemci için onaltılık makine kodunda bir uygulamadır.

11XXXX131AFE61380F6FE53E28CD9DB47DCD9DB4188EE1BDC03E29CD9DB4189BEF4504E5214CE1C9

XXXX (3-6 dahil), ayrıştırdığınız dizenin eksi 1 baytlık 16 bit adresidir.

Z80-ASCII'de kodlanmıştır:

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

(Yaklaşık, çünkü TI hesaplayıcılarının kendi karakter kümeleri vardır.)

BU NOT AsmPrgmİÇİNDE YUKARIDAKİ DAHİL DEĞİLDİR


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"}})}

Dikkat edilmesi gereken bazı noktalar: Bu sadece bir komut dosyası bloğu. Bir değişkene atanabilir veya gerekirse bir işlev adı verilebilir. Ayrıca , sonundaki argümanları .veya &önüne koyarak da çalıştırabilirsiniz . Kapatılmamış etiketleri sonlandırmak için bir son boşluk kullanır.

Tüm testleri geçer. Test komut dosyası:

$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]]
}

2

Python - 114 113 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

Python'un girinti ayrıştırıcısını tam sekme için bir boşluk, iki sekme için beş boşluk kullanmak üzere kötüye kullanır.

Düzenle 1 - range () işlevinde gereksiz bir boşluk kaydetti

Düzenleme 2 - Yanlış ayrıştırma dilbilgisi, sonlandırılmamış etiketlerle başa çıkmak için düzeltildi.

Düzenleme 3 - Etiket ağacındaki belirsizlik nedeniyle "yanlış" ayrıştırmaların oluşturulabileceği bir hata düzeltildi. Sayaç yerine yığın tabanlı bir strateji uyguladı.

Düzenle 4 - tekrar tekrar aramak için kullanılan karakterlerin kaydedilmesini önlemek için s.find olarak o olarak yeniden adlandırıldı. aynısını f.lower için de yaptı.

Düzenle 5 - üç karakter kaydederek boşluk / sekme kesmek eklendi.

Düzenle 6 - "" "* d lehine döngü hendek.


1
yerine ord(f)...kullanabileceğiniz '@'<f<'\\'için denetlemek gerekmiyorsa '\\'kullanabilirsiniz ']'yerine
gnibbler

1
5 boşluk yerine tek bir sekme kullanabilirsiniz. SO kod biçimlendirmesi yine de işleyemez :(. if ...:s+=")";c-=1else:s+="("+f;c+=1
Durumunuzda

1
for i in range(d):s+=")"olarak yeniden yazılabilir s+=")"*d. Ve 174 karakteriniz var.
cemper93

@cemper - iyi bir nokta. Ben "_" * 80 gün boyu yapmak ve golf yaparken bunu unutmak .... Ayrıca, öneriler için @ gnibbler sayesinde!
arrdem

Aslında, sana 174 karakter vardı anlamına geliyordu önce . Şimdi 159 yaşındasınız.
cemper93
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.