Trình phân tích cú pháp XML của Lập trình viên lười biếng


15

Lý lịch

Bạn đang làm việc như một lập trình viên cho một công ty bán xe. Nhiệm vụ của bạn trong tuần này là lập trình một trình phân tích cú pháp XML lấy dữ liệu về các mẫu có sẵn từ các nhà sản xuất ô tô khác nhau và in thông tin đẹp về các mẫu mới nhất. May mắn cho bạn, bộ phận kiểm tra chỉ cung cấp một trường hợp thử nghiệm! Bạn có thể viết mã vượt qua nó càng nhanh, bạn càng có nhiều thời gian cho sự trì hoãn trong suốt phần còn lại của tuần.

Đầu vào

Đầu vào của bạn chính xác là đoạn dữ liệu XML này, được cung cấp bởi bộ phận kiểm tra. Nó chứa dữ liệu về một số nhà sản xuất xe hơi, loạt xe của họ và các mô hình trong loạt này. Bạn có thể giả sử một dòng mới.

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

Đầu ra

Đầu ra của bạn là chuỗi này. Nó liệt kê các nhà sản xuất xe hơi theo thứ tự bảng chữ cái, theo sau là dấu hai chấm và số sê-ri họ tạo ra. Theo mỗi nhà sản xuất, nó liệt kê tên sê-ri, tên mô hình và mã của từng mô hình của họ, bắt đầu từ mới nhất và đi lùi theo năm. Trailing khoảng trắng và ngắt dòng là chấp nhận được, miễn là đầu ra của bạn trông giống như thế này khi được in.

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)

Quy tắc và chấm điểm

Bạn có thể viết một chức năng hoặc chương trình đầy đủ. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

Lưu ý rằng đầu vào là cố định: bạn không cần phải hỗ trợ bất kỳ đầu vào nào khác ngoài đầu vào được đưa ra ở đây. Chương trình của bạn được phép trả lại vô nghĩa hoặc thậm chí sụp đổ nếu đầu vào được sửa đổi theo bất kỳ cách nào. Bạn cũng có thể bỏ qua đầu vào và mã cứng đầu ra, nếu muốn. Tuy nhiên, bạn không được sử dụng các thư viện hoặc trình phân tích cú pháp XML hoặc HTML.


Một trình phân tích cú pháp HTML sẽ được cho phép hoặc sẽ uốn cong các quy tắc?
Hạ cấp

11
Tôi không bao giờ muốn mua một chiếc xe từ công ty này.
kirbyfan64sos

1
@vihan Tôi sẽ (khá tùy tiện) quyết định rằng các trình phân tích cú pháp HTML cũng không được phép, vì hai định dạng này rất giống nhau.
Zgarb

XSLT thì sao? ;)
Beta Decay

@BetaDecay Tôi sẽ cho phép XSLT là một ngoại lệ, vì có lẽ sẽ rất tẻ nhạt và khó chịu khi không sử dụng các hoạt động phân tích cú pháp XML trong ngôn ngữ đó. : P Và dù sao nó cũng sẽ không cạnh tranh với câu trả lời của CJam.
Zgarb

Câu trả lời:


8

CJam, 109 107 byte

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

Lưu ý rằng bốn trong số các ký tự trong chuỗi ở đầu là không thể in được.

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý tưởng

Về cơ bản, đây là một mã cứng phân tách đầu vào tại tất cả các lần xuất hiện của < , >" , chọn các khối cụ thể và xen kẽ chúng với các phần còn lại của đầu ra.

Sau khi tách đầu vào, các khối tại các chỉ số 110 , 114122Car Corporation , Corporation CarFirst and Only Model . Các mã cho chuỗi và tên có thể được tìm thấy tại các chỉ mục 116 và 126, có thể được tính bằng cách thêm 2 và 4 vào các chỉ mục của các tên. Cuối cùng, số sê-ri là độ dài của chuỗi Car Corporation chia cho 9 (rõ ràng).

Do đó, chúng tôi mã hóa phần đầu ra tương ứng với nhà sản xuất này [114 122 110]hoặc đúng hơn là chuỗi "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

Bong bóng , 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                             .....|!..

Điều này không cạnh tranh lắm, nhưng tôi không thể không đăng câu trả lời Bubblegum đầu tiên của mình cho một thách thức thực tế .

Các hexdump có thể được đảo ngược với xxd -r -c 18 > xml.bg.

Mã hoàn toàn bỏ qua đầu vào. Quá trình nén đã được thực hiện với zopfli , sử dụng định dạng DEFLATE nhưng thu được tỷ lệ tốt hơn so với (g) zip.

Cảm ơn @ Sp3000 cho -2 byte!


9

sed, 449 byte

Giả sử sed được chạy với các -nrtùy chọn.

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

Phiên bản bị đánh cắ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
Chào mừng bạn đến với Câu đố lập trình & Code Golf!
Dennis

2

Bash, 388 368 365

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

Thử nghiệm nhỏ vì:

$ 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
Ngay cả khi bạn khăng khăng tránh các ký tự và cảnh báo không thể in được, điều này có thể được thực hiện ngắn hơn rất nhiều. 1. Tệp nén của bạn chứa tên của tệp gốc , car_manufacturer.txt. 2. Một chuỗi ở đây sẽ ngắn hơn 3 byte. 3. Sử dụng zopfli thay cho vanilla gzip giúp tiết kiệm thêm 12 byte.
Dennis

Cảm ơn vì lời khuyên. Quả thực đã lưu một số byte. Nhưng để giữ tâm trạng của thử thách, sự lười biếng không khuyến khích cài đặt zopfli hoặc một trong các Chương trình nén dữ liệu PAQ. :)
LukStorms

1
Chuỗi ở đây là một golf dễ dàng mặc dù. Chỉ cần thay thế<<L bằng <<<(base encoded stuff).
Dennis

Và 3 byte cạo. Đẹp.
LukStorms
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.