Parser XML The Lazy Programmer

15

Latar Belakang

Anda bekerja sebagai programmer untuk perusahaan penjualan mobil. Tugas Anda untuk minggu ini adalah memprogram parser XML yang mengambil data tentang model yang tersedia dari berbagai produsen mobil, dan mencetak informasi yang cantik tentang model-model terbaru. Beruntung bagi Anda, departemen pengujian hanya menyediakan satu uji kasus! Semakin cepat Anda dapat menulis kode yang melewatinya, semakin banyak waktu yang Anda miliki untuk penundaan selama sisa minggu ini.

Memasukkan

Input Anda persis seperti data XML ini, disediakan oleh departemen pengujian. Ini berisi data tentang beberapa produsen mobil, seri mobil mereka, dan model dalam seri ini. Anda dapat mengasumsikan baris baru yang tertinggal.

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

Keluaran

Output Anda adalah string ini. Ini daftar pabrikan mobil dalam urutan abjad, diikuti oleh titik dua dan jumlah seri yang mereka buat. Di bawah masing-masing produsen, itu mencantumkan nama seri, nama model, dan kode masing-masing model mereka, mulai dari yang terbaru dan mundur ke tahun. Trailing whitespace dan line break dapat diterima, selama output Anda terlihat mirip dengan ini saat dicetak.

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)

Aturan dan Penilaian

Anda dapat menulis fungsi atau program lengkap. Hitungan byte terendah menang, dan celah standar tidak diizinkan.

Perhatikan bahwa input sudah diperbaiki: Anda tidak perlu mendukung input lain dari yang diberikan di sini. Program Anda diizinkan untuk mengembalikan omong kosong atau bahkan macet jika inputnya diubah dengan cara apa pun. Anda juga dapat mengabaikan input dan mengkode output, jika diinginkan. Namun, Anda tidak boleh menggunakan parser pustaka XML atau HTML atau built-in.

Zgarb
sumber
Apakah parser HTML diizinkan atau apakah itu membengkokkan aturan?
Downgoat
11
Saya tidak pernah mau membeli mobil dari perusahaan ini.
kirbyfan64sos
1
@ Vihan Saya akan (agak sewenang-wenang) memutuskan bahwa parser HTML juga tidak diperbolehkan, karena kedua formatnya sangat mirip.
Zgarb
Bagaimana dengan XSLT? ;)
Beta Decay
@ BetaDecay Saya akan mengizinkan XSLT sebagai pengecualian, karena mungkin akan sangat membosankan dan menjengkelkan untuk tidak menggunakan operasi parsing XML dalam bahasa itu. : P Dan itu tidak akan bersaing dengan jawaban CJam.
Zgarb

Jawaban:

8

CJam, 109 107 byte

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

Perhatikan bahwa empat karakter dalam string di awal tidak dapat dicetak.

Cobalah online di penerjemah CJam .

Ide

Ini pada dasarnya adalah hardcode yang membagi input pada semua kemunculan < , > dan " , memilih potongan tertentu dan interleave dengan bagian sisa dari output.

Setelah memisahkan input, potongan pada indeks 110 , 114 dan 122 adalah Car Corporation , Corporation Car dan First and Only Model . Kode untuk seri dan nama dapat ditemukan di indeks 116 dan 126, yang dapat dihitung dengan menambahkan 2 dan 4 ke indeks nama. Akhirnya, jumlah seri adalah panjang dari string Car Corporation dibagi 9 (jelas).

Dengan demikian, kami menyandikan bagian dari output yang sesuai dengan pabrikan ini sebagai [114 122 110]atau lebih tepatnya string "rzn".

Kode

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.
}
Dennis
sumber
10

Bubblegum , 227 225 byte

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                             .....|!..

Ini tidak terlalu kompetitif, tetapi saya tidak bisa menolak untuk mengirim jawaban Bubblegum pertama saya ke tantangan sebenarnya .

Hexdump dapat dibalik dengan xxd -r -c 18 > xml.bg.

Kode sepenuhnya mengabaikan input. Kompresi telah dilakukan dengan zopfli , yang menggunakan format DEFLATE tetapi mendapatkan rasio yang lebih baik daripada (g) zip.

Terima kasih kepada @ Sp3000 untuk -2 byte!

Dennis
sumber
9

sed, 449 byte

Diasumsikan sed akan dijalankan dengan -nropsi.

/\?|<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

Versi tidak disatukan:

# 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
sinar
sumber
1
Selamat Datang di Programming Puzzles & Code Golf!
Dennis
2

Bash, 388 368 365

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

Tes kecil karena:

$ 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)
LukStorms
sumber
1
Bahkan jika Anda bersikeras untuk menghindari karakter dan peringatan yang tidak patut, ini bisa menjadi jauh lebih singkat. 1. File terkompresi Anda berisi nama file asli car_manufacturer.txt,. 2. Sebuah string di sini akan lebih pendek 3 byte. 3. Menggunakan zopfli bukan vanilla gzip menyimpan 12 byte lebih banyak.
Dennis
Terima kasih atas sarannya. Memang itu menyimpan beberapa byte. Tetapi untuk tetap dalam mood tantangan, malas tidak menginstal zopfli atau salah satu Program Kompresi Data PAQ. :)
LukStorms
1
String di sini adalah golf yang mudah. Ganti saja <<Ldengan <<<(base encoded stuff).
Dennis
Dan 3 byte dicukur. Bagus.
LukStorms