Parser XML Lazy Programmer's

15

tło

Pracujesz jako programista w firmie zajmującej się sprzedażą samochodów. Twoim zadaniem na ten tydzień jest zaprogramowanie parsera XML, który pobiera dane o dostępnych modelach od różnych producentów samochodów i ładnie drukuje informacje o najnowszych modelach. Na szczęście dla ciebie dział testowy dostarczył tylko jeden przypadek testowy! Im szybciej możesz napisać kod, który go mija, tym więcej czasu masz na odwlekanie w pozostałej części tygodnia.

Wejście

Twój wkład to dokładnie ten fragment danych XML dostarczony przez dział testowy. Zawiera dane dotyczące niektórych producentów samochodów, ich serii samochodów i modeli w tych seriach. Możesz założyć końcowy znak nowej linii.

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

Wynik

Twój wynik to ten ciąg. Podaje producentów samochodów w kolejności alfabetycznej, a następnie dwukropek i liczbę wyprodukowanych serii. Pod każdym producentem wymieniono nazwę serii, nazwę modelu i kod każdego z ich modeli, zaczynając od najnowszego i cofając się z roku na rok. Dopuszczalne są końcowe spacje i podziały wierszy, pod warunkiem, że wydruk będzie wyglądał podobnie do tego.

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)

Zasady i punktacja

Możesz napisać funkcję lub pełny program. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Zauważ, że dane wejściowe są stałe: nie musisz obsługiwać żadnych innych danych wejściowych niż podane tutaj. Twój program może zwracać bzdury, a nawet awarię, jeśli dane wejściowe zostaną zmodyfikowane w jakikolwiek sposób. W razie potrzeby możesz również zignorować dane wejściowe i zakodować dane wyjściowe. Nie można jednak używać bibliotek parserów XML lub HTML ani wbudowanych funkcji.

Zgarb
źródło
Czy parser HTML byłby dozwolony, czy zaginałby reguły?
Downgoat
11
Nigdy nie chcę kupować samochodu od tej firmy.
kirbyfan64sos
1
@vihan Zdecyduję (raczej arbitralnie), że parsery HTML również nie są dozwolone, ponieważ oba formaty są tak podobne.
Zgarb
Co z XSLT? ;)
Beta Decay
@BetaDecay zezwalam na XSLT jako wyjątek, ponieważ prawdopodobnie byłoby bardzo żmudne i denerwujące, aby nie używać operacji analizowania XML w tym języku. : P I tak czy inaczej nie będzie konkurować z odpowiedzią CJam.
Zgarb,

Odpowiedzi:

8

CJam, 109 107 bajtów

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

Zauważ, że czterech znaków w ciągu na początku nie można wydrukować.

Wypróbuj online w interpretatorze CJam .

Pomysł

Jest to w zasadzie twardy kod, który dzieli dane wejściowe we wszystkich wystąpieniach < , > i " , wybiera określone fragmenty i przeplata je z pozostałymi częściami wyniku.

Po podzieleniu danych wejściowych fragmenty o indeksach 110 , 114 i 122 to Car Corporation , Corporation Car i First and Only Model . Kody serii i nazwy można znaleźć w indeksach 116 i 126, które można obliczyć, dodając 2 i 4 do indeksów nazw. Na koniec liczba serii to długość łańcucha Car Corporation podzielona przez 9 (oczywiście).

Zatem kodujemy część wyniku, która odpowiada temu producentowi, a [114 122 110]raczej ciąg "rzn".

Kod

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
źródło
10

Bubblegum , 227 225 bajtów

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

Nie jest to zbyt konkurencyjne, ale po prostu nie mogłem się oprzeć opublikowaniu mojej pierwszej odpowiedzi na Bubblegum na rzeczywiste wyzwanie .

Zrzut heksowy można odwrócić za pomocą xxd -r -c 18 > xml.bg.

Kod całkowicie ignoruje dane wejściowe. Kompresja została wykonana z zopfli , który używa formatu DEFLATE, ale uzyskuje lepszy stosunek niż (g) zip.

Dzięki @ Sp3000 za -2 bajty!

Dennis
źródło
9

sed, 449 bajtów

Zakłada, że ​​sed działa z -nropcjami.

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

Wersja bez golfa:

# 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
Promień
źródło
1
Witamy w Programowaniu Puzzle i Code Golf!
Dennis,
2

Bash, 388 368 365

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

Mały test, ponieważ:

$ 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
źródło
1
Nawet jeśli nalegasz na unikanie niedrukowalnych znaków i ostrzeżeń, można to znacznie skrócić. 1. Plik skompresowany zawiera nazwę oryginalnego pliku car_manufacturer.txt. 2. Łańcuch tutaj miałby 3 bajty krótszy. 3. Użycie zopfli zamiast waniliowego gzip pozwala zaoszczędzić jeszcze 12 bajtów.
Dennis,
Dzięki za radę. Rzeczywiście to zaoszczędziło trochę bajtów. Ale aby pozostać w nastroju wyzwania, lenistwo zniechęciło do instalowania zopfli lub jednego z programów kompresji danych PAQ. :)
LukStorms
1
Tutaj ciąg jest łatwym golfem. Wystarczy wymienić <<Lz <<<(base encoded stuff).
Dennis
I ogolono 3 bajty. Ładny.
LukStorms,