XML-аналізатор лінивого програміста


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-аналіз чи це буде згинати правила?
Пуховик

11
Я ніколи не хочу купувати машину у цієї компанії.
kirbyfan64sos

1
@vihan Я (скоріше довільно) вирішуватимуть, що HTML-аналізатори також не дозволені, оскільки два формати настільки схожі.
Згарб

Що з XSLT? ;)
бета-розпад

@BetaDecay Я хочу дозволити XSLT як виняток, оскільки це, ймовірно, буде дуже нудно і прикро не використовувати операції розбору XML на цій мові. : P І це все одно не буде конкурувати з відповіддю CJam.
Згарб

Відповіді:


8

CJam, 109 107 байт

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

Зауважте, що чотири символи в рядку на початку не друкуються.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Це в основному жорсткий код, який розбиває вхід при будь-яких явищах < , > і " , вибирає конкретні шматки і перемежовує їх з рештою частин виводу.

Розділивши вхід, фрагменти в індексах 110 , 114 і 122 - це Car Corporation , Corporation Car і перша і єдина модель . Коди для рядів та назв можна знайти в індексах 116 та 126, які можна обчислити, додавши 2 та 4 до індексів імен. Нарешті, кількість серій - це довжина струни Car Corporation, поділена на 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 на актуальний .

Шістнадцятковий відвал можна обернути назад xxd -r -c 18 > xml.bg.

Код повністю ігнорує вхідні дані. Стиснення було зроблено за допомогою zopfli , який використовує формат DEFLATE, але отримує кращі співвідношення, ніж (g) zip.

Завдяки @ Sp3000 за -2 байти!


9

sed, 449 байт

Передбачає, що sed запускається з -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
Ласкаво просимо до головоломки програмування та коду для гольфу!
Денніс

2

Баш, 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 замість ванілі gzip економить ще 12 байт.
Денніс

Дякую за пораду. Дійсно, що зберегло кілька байт. Але для того, щоб не переживати виклик, лінь відлякує встановити zopfli або одну з програм стиснення даних PAQ. :)
LukStorms

1
Тут рядок - це легкий гольф, хоча. Просто замініть <<Lна <<<(base encoded stuff).
Денніс

І поголені 3 байти. Приємно.
LukStorms
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.