Parser für Leichenschauhausdateien in DCSS

9

Bei dieser Herausforderung müssen Sie Leichenschauhausdateien aus dem schurkenhaften Spiel Dungeon Crawl Stone Soup analysieren und an STDOUT ausgeben.

Was sind diese Leichenschauhausdateien?

Wenn du stirbst, wird eine Textdatei mit den Daten dieses Charakters generiert. Sie können sehen, welche Ausrüstung der Charakter hatte, was in den letzten Runden passiert ist und wie viele Monster er getötet hat.

Eine Beispiel-Leichenschauhausdatei finden Sie hier

Die Herausforderung

Ihre Aufgabe ist es, ein Programm zu erstellen, das eine dieser Dateien aus STDIN entnimmt, analysiert und die Daten an STDOUT ausgibt.

Um diese Herausforderung etwas zu vereinfachen, müssen Sie nur den ersten Textblock analysieren. (bis zuThe game lasted <time> (<turns> turns).

Sie müssen die folgenden Informationen analysieren und ausgeben:

  • Die Versionsnummer.
  • Die Punktzahl.
  • Der Charaktername, Titel, Rasse und Klasse.
  • Die Charakterebene.
  • Die Todesursache / der Sieg.
  • Die Anzahl der Umdrehungen, die der Lauf dauerte.

Beispiel:

Dungeon Crawl Stone Soup version <version number> character file.

<score> <name> the <title> (level <level>, 224/224 HPs)
         Began as a <race> <class> on Mar 16, 2015.
         Was the Champion of the Shining One.
         <cause of death/victory>

         The game lasted 16:11:01 (<turns> turns).

Testfälle

Testfall 1 - Sieg

Eingabedatei

Beispielausgabe - Sieg:

Version: 0.16.0-8-gd9ae3a8 (webtiles)
Score: 16059087
Name: Ryuzilla the Conqueror
Character: Gargoyle Berserker
Level: 27
Cause of Death/Victory: Escaped with the Orb and 15 runes on Mar 17 2015!
Turns: 97605

Testfall 2 - Tod

Eingabedatei

Beispielausgabe - Tod:

Version: 0.16-a0-3667-g690a316 (webtiles)
Score: 462
Name: 8Escape the Ruffian
Character: Bearkin Transmuter
Level: 6
Cause of Death/Victory: Slain by an orc wielding a +0 trident (3 damage) on level 4 of the Dungeon.
Turns: 3698

Regeln

  • Dies ist also gewinnt der kürzeste Code.
  • Bei einem Unentschieden gewinnt die älteste Antwort.
  • Keine Standardlücken.
  • Die Dateieingabe muss von STDIN stammen
  • Die Ausgabe muss an STDOUT gesendet werden
  • Die Beschriftungen vor der Ausgabe (z. B. Turns:) sind optional.

Ungolfed Beispielcode zur Inspiration

Code zur Generierung von Leichenschauhausdateien in DCSS

DJgamer98
quelle
Muss die Ausgabe tatsächlich die Zeilenbeschriftungen enthalten Version:oder reicht aus, um die Informationen in derselben Reihenfolge auszugeben, eine pro Zeile?
Martin Ender
@ MartinBüttner Die Etiketten sind optional.
DJgamer98
Werden Rasse und Klasse immer jeweils ein Wort sein?
Martin Ender
@ MartinBüttner Einige Rennen und Klassen sind zwei Wörter, wie Vine Stalker, Abyssal Knight und Deep Elf.
DJgamer98
2
Gibt es eine Spezifikation dieses Leichenschauhaus-Dateiformats oder nur diese Beispiele?
Paŭlo Ebermann

Antworten:

3

Perl, 151 Bytes

148 Code + 3 Schalter ( -0, -l, -p). Ich bin sicher, das kann verbessert werden :)

Nimmt Eingaben von STDIN entgegen und druckt das Ergebnis beim Empfang von EOF.

perl -lp0e 's/\.{3}|\s/ /g;y/ //s;$_=join$\,(/(\d.*?).{15}\..(\d+).(.+?).\(.+?(\d+).+?\b(?:a|an) (.+?) o.+? ([^.!]+[.!])[^.!]*?(\d+)[^(]+\)..\3/)[0..2,4,3,5..7]'

Ungolfed:

use strict;
use warnings;

# set the input record separator to undef (the -0 switch)
$/=undef;
# read the text (the -l switch)
$_=<STDIN>;

# replace all '...' and spaces by a ' '
s/\.{3}|\s/ /g;
# squeeze all contiguous spaces into a single space
y/ //s;
# collect the captured groups into @p
my @p=
/(\d.*?).{15}\..      # version is the first string starting with a digit and ending 15 characters before the period
 (\d+).               # points is the next string with only digits
 (.+?).\(.+?          # name starts after a gap of one character
 (\d+).+?\b(?:a|an)\s # level is inside the next open paranthesis
 (.+?)\so.+?\s        # race, class occur after the 'a' or 'an' and end before ' o' i.e. (' on')
 ([^.!]+[.!])[^.!]*?  # cause of death is the a sentence ending with '.' or '!'
 (\d+)[^(]+\)..\3     # turns is the next sentence with digits within parantheses, followed by 2 characters and the player's name
/x;
$_=join"\n",@p[0..2,4,3,5..7]; # the level and race lines need to be swapped

# print the output (the -p switch)
print $_;

ideone.com

svsd
quelle
3

F #, 377 Bytes

open System.Text.RegularExpressions
let s=System.String.IsNullOrWhiteSpace>>not
let m f=Regex.Match((f+"").Split[|'\r';'\n'|]|>Seq.filter s|>Seq.take 8|>Seq.reduce(fun a z->a+z.Trim()), ".*n (.*) c.*\.([0-9]+) (.*) \(l.* (.*),.*a (.*) o.*\.(?:(S.*)|W.*(E.*)).*.T.*\((.*) .*\).").Groups|>Seq.cast<Group>|>Seq.skip 1|>Seq.map(fun z ->z.Value)|>Seq.filter s|>Seq.iter(printfn"%s")
Ebbe
quelle
3

Javascript (ES6), 297 230 Bytes

Im Moment ist dies ein testgetriebener regulärer Ausdruck.

Es ersetzt einfach die unerwünschten Informationen und behält die wichtigen Dinge.

Es wird eine anonyme Funktion erstellt, die einfach den gewünschten Text zurückgibt.

_=>_.replace(/^.+version(.*) character file\.([\n\r]+)(\d+)([^\(]+) \([^\d]+( \d+),.+\n\s+.+as a(.+) on.+\n\s+(?:Was.+One\.\n)?((?:.|\n)+[!.])\n(?:.|\n)+\((\d+)(?:.|\n)+$/,'$1\n$3\n‌​$4\n$6\n$5\n$7\n$8').replace(/\s+(\.{3} ?)?/,' ')

Ist es nicht ein Tier?


Vielen Dank für den Tipp von sysreq , dass die Etiketten optional sind. Das hat mir 67 Bytes erspart !


Sie können den resulgaren Ausdruck unter folgender Adresse testen: https://regex101.com/r/zY0sQ0/1

Ismael Miguel
quelle
Die Beschriftungen sind optional. Sie können einige Bytes sparen, indem Sie sie weglassen.
Katze
1
@sysreq Das was ...?
Ismael Miguel
2
Ich sage, _=>_.replace(/^.+version(.*) character file\.([\n\r]+)(\d+)([^\(]+) \([^\d]+( \d+),.+\n\s+.+as a(.+) on.+\n\s+(?:Was.+One\.\n)?((?:.|\n)+[!.])\n(?:.|\n)+\((\d+)(?:.|\n)+$/,'$1\n$3\n$4\n$6\n$5\n$7\n$8').replace(/\s+(\.{3} ?)?/,' ')ist eine akzeptable Lösung bei nur 230 Bytes
Katze
1
@sysreq Tut mir leid, dass ich so lange gebraucht habe, um etwas zu sagen. Ich habe den Beitrag gesehen, aber ich war auf einem Tablet. Sie haben keine Ahnung, wie schmerzhaft es ist, etwas in einer Tablette zu tun. Ich habe meinen Code durch Ihre beschriftungslose Version ersetzt. Vielen Dank für den Tipp.
Ismael Miguel
2

Python3, 472 Bytes

Ich dachte, ich könnte so viel kürzer werden. Kein Wunder, dass ich meine eigene Vorlage geschlagen habe. Führen Sie es wie python3 dcss.py morgue-file.txt.

import sys
n="\n"
s=" "
f=open(sys.argv[1],'r').read().split(n)[:11]
m=range
a=len
d=","
for i in m(a(f)):
 f[i]=f[i].split(s)
 for x in m(a(f[i])):
  f[i][x]=f[i][x].strip()
h=f[0]
g=f[10]
k=f[2]
def r(j,u):
 j=list(j)
 while u in j:
  j.remove(u)
 return"".join(j)
def l(x):
 c=s
 for i in m(a(x)):
  c+=x[i]+s
 return c.strip()
print(h[6]+s+h[7]+n+k[0]+n+g[0]+s+g[1]+s+g[2]+n+r(g[3],"(")+s+r(g[4],")")+n+r(k[5],d)+n+r(l(f[4])+l(f[5])+l(f[6])+l(f[7]),".")+n+r(g[17],d))
Katze
quelle
2

Go, 589 502 489 487 Bytes

package main;import(."fmt";."io/ioutil";"os";."strings");func d(z,ch string)string{return Map(func(r rune)rune{if IndexRune(ch,r)<0{return r};return -1},z)};func main(){x:=Split;f,_:=ReadFile(os.Args[1]);n:="\n";l:=" ";m:=",";h:=".";q:=x(string(f),n)[:11];k:=x(q[0],l);y:=x(q[10],l);u:=x(q[2],l);g:="";for _,e:=range Fields(d(q[4],n+h)+l+d(q[5],n+h)+l+d(q[6],n+h)+l+d(q[7],n+h)){g=g+e+l};Print(k[6]+l+k[7]+n+u[0]+n+y[0]+l+y[1]+l+y[2]+n+d(y[3]+l+y[4],"()")+n+d(u[5],m)+n+g+n+d(y[17],m))}

nach dem Laufen go fmt, go fixund go vethier ist die "ungolfed" Version:

package main

import (
    . "fmt"
    . "io/ioutil"
    "os"
    . "strings"
)

func d(z, ch string) string {
    return Map(func(r rune) rune {
        if IndexRune(ch, r) < 0 {
            return r
        }
        return -1
    }, z)
}
func main() {
    x := Split
    f, _ := ReadFile(os.Args[1])
    n := "\n"
    l := " "
    m := ","
    h := "."
    q := x(string(f), n)[:11]
    k := x(q[0], l)
    y := x(q[10], l)
    u := x(q[2], l)
    g := ""
    for _, e := range Fields(d(q[4], n+h) + l + d(q[5], n+h) + l + d(q[6], n+h) + l + d(q[7], n+h)) {
        g = g + e + l
    }
    Print(k[6] + l + k[7] + n + u[0] + n + y[0] + l + y[1] + l + y[2] + n + d(y[3]+l+y[4], "()") + n + d(u[5], m) + n + g + n + d(y[17], m))
}

Bearbeiten: Die Verwendung von Punktimporten hilft sehr.

Ziemlich selbsterklärend, aber ich kann es bei Bedarf erklären. Dies ist mein erstes "echtes" Go-Programm und ich bin noch ein Anfänger bei Codegolf, daher sind Tipps willkommen!

Bearbeiten: Sie sagten "Nehmen Sie eine Datei von STDIN", und Sie können dieses Skript (falls installiert) ausführen, indem Sie go install <foldername>und dann <binaryname> morgue-file.txtoder ausführengo run main.go morgue.txt

Katze
quelle