Analizador de archivos de morgue DCSS

9

En este desafío, debes analizar los archivos de la morgue del juego roguelike Dungeon Crawl Stone Soup y enviarlos a STDOUT.

¿Qué son estos archivos de la morgue?

Cuando mueres, se genera un archivo de texto con los datos de ese personaje dentro. Puedes ver qué equipo tenía el personaje, qué sucedió durante los últimos turnos y cuántos monstruos ha matado.

Puede encontrar un ejemplo de archivo de la morgue aquí

El reto

Su trabajo es crear un programa que tome uno de esos archivos de STDIN, lo analice y envíe los datos a STDOUT.

Para hacer este desafío un poco más fácil, solo tiene que analizar el primer bloque de texto. (hastaThe game lasted <time> (<turns> turns).

Debe analizar y generar la siguiente información:

  • El número de versión.
  • El marcador.
  • El nombre del personaje, título, raza y clase.
  • El nivel del personaje.
  • La causa de la muerte / victoria.
  • La cantidad de turnos que duró la carrera.

Ejemplo:

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

Casos de prueba

Caso de prueba 1 - Victoria

Fichero de entrada

Ejemplo de salida - Victoria:

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

Caso de prueba 2 - Muerte

Fichero de entrada

Ejemplo de salida - Muerte:

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

Reglas

  • Este es el por lo que gana el código más corto.
  • En caso de empate, gana la respuesta más antigua.
  • No hay lagunas estándar.
  • La entrada del archivo debe tomarse de STDIN
  • La salida debe enviarse a STDOUT
  • Las etiquetas antes de la salida (ej. Turns:) Son opcionales.

Código de muestra sin golf para inspirarse

Código de generación de archivos Morgue en DCSS

DJgamer98
fuente
¿El resultado realmente necesita contener las etiquetas de línea como Version:o es suficiente para generar los datos en el mismo orden, uno por línea?
Martin Ender
@ MartinBüttner Las etiquetas son opcionales.
DJgamer98
¿La raza y la clase siempre serán una palabra cada una?
Martin Ender
@ MartinBüttner Algunas razas y clases son dos palabras, como Vine Stalker, Abyssal Knight y Deep Elf.
DJgamer98
2
¿Existe una especificación de este formato de archivo de morgue, o solo estos ejemplos?
Paŭlo Ebermann

Respuestas:

3

Perl, 151 bytes

148 código + 3 interruptores ( -0, -l, -p). Estoy seguro de que esto se puede mejorar :)

Toma información de STDIN e imprime el resultado al recibir 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]'

Sin golf:

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
fuente
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")
reflujo
fuente
3

Javascript (ES6), 297 230 bytes

Por ahora, esta es una expresión regular basada en pruebas.

Simplemente reemplaza la información no deseada y mantiene las cosas importantes.

Crea una función anónima que simplemente devuelve el texto deseado.

_=>_.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} ?)?/,' ')

¿No es una bestia?


Gracias por el consejo de sysreq sobre que las etiquetas son opcionales. ¡Eso me salvó 67 bytes !


Puede probar la expresión resultante en: https://regex101.com/r/zY0sQ0/1

Ismael Miguel
fuente
Las etiquetas son opcionales; puede guardar bastantes bytes omitiéndolos.
gato
1
@sysreq ¿Qué ...?
Ismael Miguel
2
Estoy diciendo que _=>_.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} ?)?/,' ')es una solución aceptable a solo 230 bytes
cat
1
@sysreq Lo siento por tomar tanto tiempo para decir algo. He estado viendo la publicación pero estaba en una tableta. No tienes idea de lo doloroso que es hacer algo en una tableta. He reemplazado mi código con su versión sin etiqueta. Muchas gracias por la propina.
Ismael Miguel
2

Python3, 472 bytes

Pensé que sería capaz de acortarme mucho más. Sin embargo, no me sorprende que haya superado mi propia sumisión. Ejecútalo como 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))
gato
fuente
2

Ir, 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))}

despues de correr go fmt , go fixy go vetaquí está la versión "sin golf":

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))
}

Editar: usar punto-importaciones ayuda mucho.

Bastante claro, pero puedo explicar si es necesario. Este es mi primer programa Go 'real' y todavía soy un principiante en codegolf, ¡así que los consejos son bienvenidos!

Editar: usted dijo "tomar un archivo de STDIN", y puede ejecutar este script (si tiene instalado) ejecutando go install <foldername>y luego <binaryname> morgue-file.txtogo run main.go morgue.txt

gato
fuente