ตัวแยกวิเคราะห์ XML ของ Lazy Programmer


15

พื้นหลัง

คุณกำลังทำงานเป็นโปรแกรมเมอร์ให้กับ บริษัท ขายรถยนต์ งานของคุณในสัปดาห์นี้คือการเขียนโปรแกรมตัวแยกวิเคราะห์ XML ที่ใช้ในข้อมูลเกี่ยวกับรุ่นที่มีจำหน่ายจากผู้ผลิตรถยนต์รายอื่นและพิมพ์ข้อมูลเกี่ยวกับรุ่นใหม่ล่าสุด โชคดีสำหรับคุณแผนกทดสอบได้จัดให้มีเพียงหนึ่งกรณีทดสอบ! ยิ่งคุณเขียนรหัสได้เร็วขึ้นเท่าไหร่คุณก็ยิ่งมีเวลาในการผัดวันประกันพรุ่งในช่วงที่เหลือของสัปดาห์

อินพุต

การป้อนข้อมูลของคุณคือว่างานชิ้นนี้ของข้อมูล XML, จัดทำโดยแผนกทดสอบ มันมีข้อมูลเกี่ยวกับผู้ผลิตรถยนต์บางรุ่นรถยนต์และรุ่นในซีรี่ส์เหล่านี้ คุณอาจถือว่าขึ้นบรรทัดใหม่

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

เอาท์พุต

ผลลัพธ์ของคุณคือสตริงนี้ มันแสดงรายการผู้ผลิตรถยนต์ตามลำดับตัวอักษรตามด้วยเครื่องหมายจุดคู่และจำนวนชุดที่พวกเขาทำ ภายใต้ผู้ผลิตแต่ละรายชื่อชุดชื่อชื่อรุ่นและรหัสของแต่ละรุ่นเริ่มต้นจากรุ่นใหม่ล่าสุดและไปข้างหลังในแต่ละปี ช่องว่างต่อท้ายและตัวแบ่งบรรทัดเป็นที่ยอมรับตราบใดที่ผลลัพธ์ของคุณมีลักษณะใกล้เคียงกับสิ่งนี้เมื่อพิมพ์ออกมา

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)

กฎและเกณฑ์การให้คะแนน

คุณสามารถเขียนฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบ จำนวนไบต์ต่ำสุดที่ชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

โปรดทราบว่าอินพุตได้รับการแก้ไขแล้ว: คุณไม่จำเป็นต้องรองรับอินพุตอื่น ๆ นอกเหนือจากอินพุตที่ให้ไว้ที่นี่ โปรแกรมของคุณได้รับอนุญาตให้ส่งคืนข้อมูลไร้สาระหรือเกิดความผิดพลาดหากอินพุตได้รับการแก้ไขด้วยวิธีการใด ๆ นอกจากนี้คุณยังอาจละเว้นการป้อนข้อมูลและรหัสยากเอาท์พุทถ้าต้องการ อย่างไรก็ตามคุณไม่สามารถใช้ไลบรารีตัวแยกวิเคราะห์ XML หรือ HTML หรือบิวด์อินได้


ตัวแยกวิเคราะห์ HTML จะได้รับอนุญาตหรือว่าจะเป็นการดัดกฎหรือไม่
Downgoat

11
ฉันไม่ต้องการซื้อรถยนต์จาก บริษัท นี้
kirbyfan64sos

1
@vihan ฉันจะ (โดยพลการ) ตัดสินใจว่า HTML parsers ไม่ได้รับอนุญาตเช่นกันเนื่องจากทั้งสองรูปแบบคล้ายกันมาก
Zgarb

XSLT เกี่ยวกับอะไร? ;)
Beta Decay

@BetaDecay ฉันจะอนุญาตให้ XSLT เป็นข้อยกเว้นเนื่องจากอาจเป็นเรื่องที่น่าเบื่อและน่ารำคาญที่จะไม่ใช้การแยกวิเคราะห์ XML ในภาษานั้น : P และมันก็ไม่สามารถแข่งขันกับคำตอบ CJam ได้
Zgarb

คำตอบ:


8

CJam, 109 107 ไบต์

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

โปรดทราบว่าอักขระสี่ตัวในสตริงที่จุดเริ่มต้นนั้นไม่สามารถพิมพ์ได้

ลองใช้ออนไลน์ในล่าม CJam

ความคิด

นี่คือฮาร์ดโค้ดที่แยกอินพุตที่เกิดขึ้นทุก< , >และ"เลือกชิ้นเฉพาะและ interleaves พวกเขาด้วยส่วนที่เหลือของการส่งออก

หลังจากที่แยกใส่ชิ้นที่ดัชนี110 , 114และ122มีCar Corporation , บริษัท รถยนต์และครั้งแรกและเพียงรุ่น รหัสสำหรับซีรีส์และชื่อสามารถพบได้ที่ดัชนี 116 และ 126 ซึ่งสามารถคำนวณได้โดยการเพิ่ม 2 และ 4 เข้ากับดัชนีของชื่อ ในที่สุดจำนวนชุดคือความยาวของสตริงคาร์คอร์ปอเรชั่นโดยหารด้วย9 (ชัด)

ดังนั้นเราจึงเข้ารหัสส่วนหนึ่งของการส่งออกที่สอดคล้องกับผู้ผลิตนี้เป็นหรือมากกว่าสตริง[114 122 110]"rzn"

รหัส

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

Bubblegum , 227 225 ไบต์

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

นี่ไม่ใช่การแข่งขันสูงนัก แต่ฉันไม่ได้ที่จะโพสต์คำตอบ Bubblegum แรกของฉันต่อท้าทายที่

hexdump xxd -r -c 18 > xml.bgสามารถกลับด้วย

รหัสไม่สนใจอินพุตทั้งหมด ทำการบีบอัดด้วยzopfliซึ่งใช้รูปแบบ DEFLATE แต่ได้อัตราส่วนที่ดีกว่า (g) zip

ขอบคุณ @ Sp3000 สำหรับ -2 ไบต์!


9

sed, 449 ไบต์

สมมติว่าจะทำงานด้วย-nrตัวเลือก

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

เวอร์ชันที่ไม่ถูกปรับแต่ง:

# 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
ยินดีต้อนรับสู่ Programming Puzzles & Code Golf!
Dennis

2

Bash, 388 368 365

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

ทดสอบเล็กน้อยเพราะ:

$ 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
แม้ว่าคุณจะยืนยันในการหลีกเลี่ยงอักขระและคำเตือนที่ไม่สามารถพิมพ์ได้สิ่งนี้สามารถทำให้สั้นลงได้มาก 1. car_manufacturer.txtการบีบอัดไฟล์ของคุณมีชื่อของไฟล์ต้นฉบับ 2. สตริงที่นี่จะสั้นกว่า 3 ไบต์ 3. การใช้ zopfli แทน vanilla gzip จะช่วยประหยัดได้ 12 ไบต์
Dennis

ขอบคุณสำหรับคำแนะนำ. แน่นอนที่บันทึกบางไบต์ แต่เพื่อให้อยู่ในอารมณ์ของความท้าทายความขี้เกียจแนะนำให้ติดตั้ง zopfli หรือหนึ่งในโปรแกรมการบีบอัดข้อมูล PAQ :)
LukStorms

1
สายที่นี่เป็นสนามกอล์ฟที่ง่าย เพียงแค่เปลี่ยนด้วย<<L <<<(base encoded stuff)
เดนนิส

และโกนด้วย 3 ไบต์ ดี
LukStorms
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.