Der XML-Parser des Lazy Programmer


15

Hintergrund

Sie arbeiten als Programmierer für eine Autoverkaufsfirma. Ihre Aufgabe für diese Woche ist es, einen XML-Parser zu programmieren, der Daten zu verfügbaren Modellen verschiedener Autohersteller aufnimmt und Informationen zu den neuesten Modellen druckt. Zum Glück hat die Testabteilung nur einen Testfall zur Verfügung gestellt! Je schneller Sie Code schreiben können, der ihn übergibt, desto mehr Zeit steht Ihnen für den Rest der Woche zur Verfügung.

Eingang

Ihre Eingabe besteht genau aus diesen XML-Daten, die von der Testabteilung bereitgestellt werden. Es enthält Daten zu einigen Autoherstellern, ihren Fahrzeugserien und den Modellen dieser Serien. Sie können von einem nachgestellten Zeilenumbruch ausgehen.

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

Ausgabe

Ihre Ausgabe ist diese Zeichenfolge. Es listet die Autohersteller in alphabetischer Reihenfolge auf, gefolgt von einem Doppelpunkt und der Anzahl der Serien, die sie herstellen. Unter jedem Hersteller werden der Serienname, der Modellname und der Code jedes einzelnen Modells aufgelistet, beginnend mit dem neuesten Modell und rückwärts nach Jahr. Nachgestellte Leerzeichen und Zeilenumbrüche sind zulässig, sofern Ihre Ausgabe beim Drucken ähnlich aussieht.

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)

Regeln und Wertung

Sie können entweder eine Funktion oder ein vollständiges Programm schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig.

Beachten Sie, dass die Eingabe fest ist: Sie müssen keine anderen Eingaben als die hier angegebene unterstützen. Ihr Programm kann Unsinn zurückgeben oder sogar abstürzen, wenn die Eingabe in irgendeiner Weise geändert wird. Bei Bedarf können Sie auch die Eingabe ignorieren und die Ausgabe hart codieren. Möglicherweise verwenden Sie jedoch keine XML- oder HTML-Parser-Bibliotheken oder integrierten Funktionen.


Wäre ein HTML-Parser erlaubt oder würde das die Regeln biegen?
Downgoat

11
Ich möchte nie ein Auto von dieser Firma kaufen.
kirbyfan64sos

1
@vihan Ich werde (eher willkürlich) entscheiden, dass HTML-Parser auch nicht erlaubt sind, da die beiden Formate so ähnlich sind.
Zgarb

Was ist mit XSLT? ;)
Beta Decay

@BetaDecay Ich werde XSLT als Ausnahme zulassen, da es wahrscheinlich sehr mühsam und ärgerlich wäre, keine XML-Parsing-Operationen in dieser Sprache zu verwenden. : P Und es wird sowieso nicht mit der CJam-Antwort konkurrieren.
Zgarb,

Antworten:


8

CJam, 109 107 Bytes

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

Beachten Sie, dass vier der Zeichen in der Zeichenfolge am Anfang nicht druckbar sind.

Probieren Sie es online im CJam-Interpreter aus .

Idee

Dies ist im Grunde ein Hardcode, der die Eingabe bei jedem Auftreten von < , > und " aufteilt, bestimmte Blöcke auswählt und sie mit den übrigen Teilen der Ausgabe verschachtelt.

Nach der Aufteilung der Eingabe lauten die Blöcke bei den Indizes 110 , 114 und 122 " Car Corporation" , " Corporation Car" und " First and Only Model" . Die Codes für Serien und Namen finden Sie in den Indizes 116 und 126, die durch Addition von 2 und 4 zu den Indexen der Namen berechnet werden können. Schließlich ist die Anzahl der Serien die Länge des Strings Car Corporation geteilt durch 9 (offensichtlich).

Wir kodieren also den Teil der Ausgabe, der diesem Hersteller entspricht, als [114 122 110]oder vielmehr den String"rzn" .

Code

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 Bytes

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

Das ist nicht sehr konkurrenzfähig, aber ich konnte einfach nicht widerstehen, meine erste Bubblegum-Antwort auf eine Herausforderung der .

Der Hexdump kann mit umgekehrt werden xxd -r -c 18 > xml.bg.

Der Code ignoriert die Eingabe vollständig. Die Komprimierung wurde mit zopfli durchgeführt , das das DEFLATE-Format verwendet, aber ein besseres Verhältnis als (g) zip erzielt.

Danke an @ Sp3000 für -2 Bytes!


9

sed, 449 bytes

Vorausgesetzt, sed wird mit den -nrOptionen ausgeführt.

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

# 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
Willkommen bei Programming Puzzles & Code Golf!
Dennis

2

Bash, 388 368 365

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

Kleiner Test, weil:

$ 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
Auch wenn Sie darauf bestehen, nicht druckbare Zeichen und Warnungen zu vermeiden, kann dies erheblich verkürzt werden. 1. Ihre komprimierte Datei enthält den Namen der Originaldatei car_manufacturer.txt. 2. Eine Here-Zeichenfolge wäre 3 Byte kürzer. 3. Die Verwendung von zopfli anstelle von Vanille-Gzip spart 12 weitere Bytes.
Dennis

Danke für den Hinweis. Das hat in der Tat ein paar Bytes gespart. Um der Herausforderung gewachsen zu sein, riet Faulheit davon ab, zopfli oder eines der PAQ-Datenkomprimierungsprogramme zu installieren. :)
LukStorms

1
Die Here-Saite ist jedoch ein einfaches Golfspiel. Ersetzen Sie einfach <<Lmit <<<(base encoded stuff).
Dennis

Und 3 Bytes rasiert. Nett.
LukStorms,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.