Tembel Programcı'nın XML Ayrıştırıcısı


15

Arka fon

Bir araba satış şirketi için programcı olarak çalışıyorsunuz. Bu haftaki göreviniz, farklı otomobil üreticilerinin mevcut modelleri hakkında veri alan bir XML ayrıştırıcıyı programlamak ve en yeni modeller hakkında güzel bilgiler yazdırmaktır. Neyse ki sizin için, test departmanı sadece bir test örneği sağladı! Daha hızlı geçen kodu yazabilir, haftanın geri kalanında erteleme için daha fazla zamanınız olur.

Giriş

Girişiniz , test departmanı tarafından sağlanan tam olarak bu XML verisi parçasıdır. Bazı otomobil üreticileri, otomobil serileri ve bu serideki modeller hakkında veriler içerir. Sonunda bir satırsonu olduğunu varsayabilirsiniz.

<?xml version="1.0" ?>
<products>
  <manufacturer name="Test Manufacturer 1">
    <series title="Supercar" code="S1">
      <model>
        <name>Road Czar</name>
        <code>C</code>
        <year>2011</year>
      </model>
      <model>
        <name>Ubervehicle</name>
        <code>U</code>
        <year>2013</year>
      </model>
      <model>
        <name>Incredibulus</name>
        <code>I</code>
        <year>2015</year>
      </model>
      <model>
        <name>Model 1</name>
        <code>01</code>
        <year>2010</year>
      </model>
    </series>
    <series title="Test series 22" code="Test">
      <model>
        <name>Test model asdafds</name>
        <code>TT</code>
        <year>2014</year>
      </model>
    </series>
  </manufacturer>
  <manufacturer name="Car Corporation">
    <series title="Corporation Car" code="CC">
      <model>
        <name>First and Only Model</name>
        <code>FOM</code>
        <year>2012</year>
      </model>
    </series>
  </manufacturer>
  <manufacturer name="Second Test Manufacturer">
    <series title="AAAAAAAAAAAAAA" code="D">
      <model>
        <name>Some older model</name>
        <code>O</code>
        <year>2011</year>
      </model>
      <model>
        <name>The newest model</name>
        <code>N</code>
        <year>2014</year>
      </model>
    </series>
    <series title="BBBBBBBBBBBBBBB" code="asdf">
      <model>
        <name>Another newest model here</name>
        <code>TT</code>
        <year>2015</year>
      </model>
    </series>
  </manufacturer>
</products>

Çıktı

Çıktınız bu dizedir. Otomobil üreticilerini alfabetik sırayla, ardından da iki nokta üst üste ve yaptıkları seri sayısını listeler. Her üreticinin altında, modellerinin her birinin seri adını, model adını ve kodunu, en yenisinden başlayarak ve her yıl geriye doğru listeler. Çıktınız yazdırıldığında buna benzediği sürece, boşluk ve satır sonları kabul edilebilir.

Car Corporation: 1 series
  Corporation Car, First and Only Model (CC-FOM)
Second Test Manufacturer: 2 series
  BBBBBBBBBBBBBBB, Another newest model here (asdf-TT)
  AAAAAAAAAAAAAA, The newest model (D-N)
  AAAAAAAAAAAAAA, Some older model (D-O)
Test Manufacturer 1: 2 series
  Supercar, Incredibulus (S1-I)
  Test series 22, Test model asdafds (Test-TT)
  Supercar, Ubervehicle (S1-U)
  Supercar, Road Czar (S1-C)
  Supercar, Model 1 (S1-01)

Kurallar ve Puanlama

Bir işlev veya tam program yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Girişin sabit olduğunu unutmayın: burada verilen dışında başka girişleri desteklemenize gerek yoktur. Giriş herhangi bir şekilde değiştirilirse, programınızın saçma veya hatta çökmesine izin verilir. İsterseniz girişi yoksayabilir ve çıktıyı kodlayabilirsiniz. Ancak, olabilir değil XML veya HTML ayrıştırıcı kütüphaneler veya yerleşik ins kullanın.


Bir HTML ayrıştırıcıya izin verilir mi yoksa kurallar bükülür mü?
Downgoat

11
Bu şirketten asla araba almak istemiyorum.
kirbyfan64sos

1
@vihan (Oldukça isteğe bağlı olarak) HTML ayrıştırıcılarına da izin verilmeyeceğine karar vereceğim, çünkü iki biçim çok benzer.
Zgarb

XSLT ne olacak? ;)
Beta Çürümesi

Muhtemelen çok sıkıcı ve sinir bozucu olurdu, çünkü ben bir istisna olarak XSLT İzin veriyorum @BetaDecay değil o dilde kullanım XML ayrıştırma işlemlerine. : P Ve yine de CJam cevabı ile rekabet etmeyecek.
Zgarb

Yanıtlar:


8

CJam, 109 107 bayt

"rzn ¸À¨ 4T\$D"S/q"<>"'"er'"/
f{\:i2/_E5bf.+.+\ff=)1<_s,9/+":  series
"2/.+\"  ,  ()
-"2/Z4e\f.\}

Baştaki dizedeki karakterlerden dördünün yazdırılamaz olduğunu unutmayın.

CJam yorumlayıcısında çevrimiçi deneyin .

Fikir

Bu temelde, girişi < , > ve " tüm örneklerinde ayıran, belirli parçaları seçen ve bunları çıktının geri kalan bölümleriyle araya getiren bir sabit koddur .

Bölme katkısının sağlanmasının ardından endeksler de parçalar 110 , 114 ve 122 olan Car Corporation , Corporation, Araba ve İlk ve Tek Modeli . Seri ve isim kodları 116 ve 126 endekslerinde bulunabilir ve adların indekslerine 2 ve 4 eklenerek hesaplanabilir. Son olarak, seri sayısı, Car Corporation dizesinin uzunluğunun 9'a (açıkçası) bölünmesidir .

Böylece, çıktının bu üreticiye karşılık gelen kısmını [114 122 110]dize olarak kodlarız "rzn".

kod

e# Split the string at spaces.

"rzn ¸À¨ 4T\$D"S/

e# After replacing characters with their code points, this will be the result:
e# [[114 122 110] [184 192 144 168 144 152 140] [12 52 84 92 12 36 12 20 12 68 8]]

e# Read from STDIN, replace < and > with " and split at double quotes.

q"<>"'"er'"/ 

f{       e# For each chunk of the split string, push the split input; then:
\:i2/    e# Replace characters with character codes and split into chunks of
         e# length 2.
_E5b     e# Copy the result and push [2 4].
f.+      e# Replace each pair [I J] in the copy with [I+2 J+4].
.+       e# Vectorized concatenation.
         e# For the first chunk, we've achieved
         e# [114 122 110] -> [[114 122] [110]]
         e#               -> [[114 122] [110]] [[116 126] [110 112 4]]
         e#               -> [[114 122 116 126] [110 112 4]]
\ff=     e# Replace each integer with the chunk of the split input at that index.
)1<      e# Pop the first chunk and reduce it to the first string.
_s,9/    e# Divide that strings length by 9 and append the integer to the array.
":  series
"2/      e# Push [": " " s" "er" "ie" "s\n"].
.+       e# Vectorized concatenation; pushes the manufacturer line.
\        e# Swap the remaining strings on top of the stack.
"  ,  ()
-"2/     e# Push ["  " ", " " (" ")\n" "-"].
Z4e\     e# Swap the chunks at indexes 3 and 4.
\f.\     e# Interleave both arrays of strings.
}

10

Sakız , 227 225 bayt

0000000: 6d 50 45 b6 02 31 10 dc cf 29 6a 87 eb 92 1d ee 0e 07  mPE..1...)j.......
0000012: 08 93 1e 3c e1 45 be 9d fe 37 ae bd 2b 7d 95 54 85 41  ...<.E...7..+}.T.A
0000024: 55 9b 83 36 c2 ad b5 2a a1 00 4b 66 4d 36 c0 23 0f f6  U..6...*..KfM6.#..
0000036: a5 d1 58 1b eb 20 94 c4 50 ed 7e d1 d7 92 76 88 57 ab  ..X.. ..P.~...v.W.
0000048: 99 c6 b0 9f 08 a6 14 6a 96 66 c4 9e be 50 3e 12 a1 f3  .......j.f...P>...
000005a: 86 4c 09 c5 7b 67 e5 f9 d2 28 2b ed 56 64 a0 e8 9b 83  .L..{g...(+.Vd....
000006c: d8 9f 3a 99 20 c4 85 95 51 66 36 4b 70 ac fc 74 69 cc  ..:. ...Qf6Kp..ti.
000007e: 56 f4 9c 88 d7 32 83 4f c6 a9 de 13 f4 4e 92 b9 1b 87  V....2.O.....N....
0000090: 89 e0 6d 24 0a 4f 33 a7 fe 40 26 e4 37 a3 ad 42 43 72  ..m$.O3..@&.7..BCr
00000a2: bd f0 3b 6f 11 9f 16 32 ed 04 eb a7 fc d9 8d 62 91 f7  ..;o...2.......b..
00000b4: dc 97 f0 6a 11 49 f6 1e b9 cb fc 7b dd 7c 41 e6 8b 56  ...j.I.....{.|A..V
00000c6: eb 70 47 a7 b6 f9 b3 3c d1 42 a2 fa 27 cc 49 ac 3e 89  .pG....<.B..'.I.>.
00000d8: 97 ff 2e 9c a4 7c 21 f1 0f                             .....|!..

Bu çok rekabetçi değil, ama ilk Bubblegum cevabımı gerçek bir sorununa .

Hexdump ile ters çevrilebilir xxd -r -c 18 > xml.bg.

Kod girişi tamamen yok sayar. DEFLATE formatını kullanan ancak (g) zip'ten daha iyi bir oran elde eden zopfli ile sıkıştırma yapılmıştır .

-2 bayt için @ Sp3000'e teşekkürler!


9

sed, 449 bayt

Sed -nrseçenekleriyle çalıştırılacağını varsayar .

/\?|<p/d;:M
/<ma/{s/.*"(.*)".*/Q\1: X series/;/C/ s/X/1/;s/X/2/;H;d}
/<se/{s/.*"([^"]*)".*"([^"]*)".*/@\1!\2/;H;d}
/<mo/{
G;s/.*@(.*)*$/\1/;x;s/@(.*)*$//;x;:A N
/<\/m/!bA
s/\n/!/g;s/  +//g;s|<[/a-z]*>||g;s/(.*)!(.*)!(.*)!(.*)!(.*)!/%\1, \3 (\2-\4)@\1!\2/;H}
/<\/se/{x;s/\n*@.*$//;x}
$!{n;bM}
x;s/\n//g;s/Q(.*)Q(.*)%(.*)Q(.*)/\2\n  \3\n\4\n\1/
s/%(.*)%(.*)%(.*)\n(.*)%(.*)%(.*)%(.*)%(.*)%(.*)/\n  \3\n  \2\n  \1\n\4\n  \7\n  \9\n  \6\n  \5\n  \8/;p

Ungolfed sürümü:

# Remove first 2 lines
/\?|<p/ d

:M
#manufacturer
/<ma/ {
    s/.*"(.*)".*/Q\1: X series/
    #Car corp
    /C/ s/X/1/
    #other
    s/X/2/
    H
    d
}

#series: store in hold buffer. (treating the hold buffer as a list, with @ as a delimeter)
/<se/{
    s/.*"([^"]*)".*"([^"]*)".*/@\1!\2/
    H
    d
}
/<mo/ {
    # pull series from hold buffer
    G
    s/.*@(.*)*$/\1/

    # remove series from hold buffer
    x
    s/@(.*)*$//
    x

    # Concatenate model into one line
    :A N
    /<\/m/ !{
        bA
    }
    s/\n/!/g

    # Remove junk
    s/  +//g
    s|<[/a-z]*>||g

    # Append formatted line to hold buffer, replace series at the end
    s/(.*)!(.*)!(.*)!(.*)!(.*)!/%\1, \3 (\2-\4)@\1!\2/
    H
}
/<\/se/ {
    #pop series name
    x
    s/\n*@.*$//
    x
}

$ ! {
    n
    b M
}
# end of loop

x
s/\n//g

# "sort"
s/Q(.*)Q(.*)%(.*)Q(.*)/\2\n  \3\n\4\n\1/
s/%(.*)%(.*)%(.*)\n(.*)%(.*)%(.*)%(.*)%(.*)%(.*)/\n  \3\n  \2\n  \1\n\4\n  \7\n  \9\n  \6\n  \5\n  \8/
p

1
Programlama Bulmacaları ve Kod Golf hoş geldiniz!
Dennis

2

Bash, 388 368 365

base64 -d<<<H4sICKVS9FUCA2hlcmUAbVFBasMwELwH8oc92mBD5GNuqUogB9dQOw9QpDUWKFJYWS3t6yvJtI3T7k07szOzKy4IuKObIzFrZ/fAwCNp9NsN3APABVVw1ORnEFZBZ80HtE6hgYLz+ti15XbTo3QRGzCSWmHDKOQcCGkPzZ3q07oqOFg3T0hg8T1NXrNqbCAUwquxHoYyzR1WVcEw4XqkeK5f/mX27orgjIoeP8wuMv8EBbaO2ocbkkybn6wkVPoSTPBQ9Kw+ZaessPChaarlvXjE6GJUkZx63zv8Cp4vSG84aWkw650f8FcnFPDP+D0J5Q/ocnmWsR0rvwC2OTuexgEAAA==|zcat

Küçük test çünkü:

$ bash ./go_procrastination.sh cars.xml
Car Corporation: 1 series
  Corporation Car, First and Only Model (CC-FOM)
Second Test Manufacturer: 2 series
  BBBBBBBBBBBBBBB, Another newest model here (asdf-TT)
  AAAAAAAAAAAAAA, The newest model (D-N)
  AAAAAAAAAAAAAA, Some older model (D-O)
Test Manufacturer 1: 2 series
  Supercar, Incredibulus (S1-I)
  Test series 22, Test model asdafds (Test-TT)
  Supercar, Ubervehicle (S1-U)
  Supercar, Road Czar (S1-C)
  Supercar, Model 1 (S1-01)

1
Yazdırılamayan karakterlerden ve uyarılardan kaçınmakta ısrar etseniz bile, bu çok daha kısa yapılabilir. 1. Sıkıştırılmış dosyanız orijinal dosyanın adını içerir car_manufacturer.txt,. 2. Burada dizge 3 bayt daha kısa olacaktır. 3. Vanilya gzip yerine zopfli kullanmak 12 bayt daha tasarruf sağlar.
Dennis

Tavsiye için teşekkürler. Gerçekten de bazı baytlar kurtardı. Ancak meydan okuma havasında kalmak için, tembellik zopfli veya PAQ Veri Sıkıştırma Programlarından birini yüklemekten vazgeçti. :)
LukStorms

1
Burada dize olsa kolay bir golf olduğunu. Sadece yerini <<Lile <<<(base encoded stuff).
Dennis

Ve 3 bayt tıraş oldu. Güzel.
LukStorms
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.