Аналізатор файлів морг DCSS


9

У цьому виклику вам потрібно розібрати файли моргу з шахрайської гри Dungeon Crawl Stone Soup та вивести його на STDOUT.

Що це за файли моргу ??

Коли ви помираєте, генерується текстовий файл із даними цього персонажа всередині. Ви можете бачити, яку техніку мав персонаж, що сталося протягом останніх кількох поворотів та скільки монстрів він убив.

Ви можете знайти приклад файлу моргу тут

Змагання

Ваше завдання - створити програму, яка бере один із цих файлів зі STDIN, аналізує її та виводить дані в STDOUT.

Щоб зробити цей виклик трохи простішим, вам потрібно лише розібрати перший блок тексту. (Аж доThe game lasted <time> (<turns> turns).

Вам потрібно проаналізувати та вивести таку інформацію:

  • Номер версії
  • Рахунок.
  • Ім'я персонажа, назва, раса та клас.
  • Рівень характеру.
  • Причина смерті / перемоги.
  • Кількість витків тривала пробіг.

Приклад:

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

Випробування

Тестовий випадок 1 - Перемога

Вхідний файл

Приклад виведення - Перемога:

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

Тестовий випадок 2 - Смерть

Вхідний файл

Приклад виведення - Смерть:

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

Правила

  • Це є тому виграє найкоротший код.
  • У разі вирівнювання виграє найстаріша відповідь.
  • Немає стандартних лазівки
  • Введення файлу потрібно взяти з STDIN
  • Вихідні дані повинні бути надіслані до STDOUT
  • Мітки перед виходом (наприклад Turns:) необов’язкові.

Код зразка без вогків для натхнення

Код генерації файлів Морга в DCSS


Чи має насправді висновок містити мітки рядків на кшталт Version:або достатньо для виведення фрагментів інформації в одному порядку, по одному на рядок?
Мартін Ендер

@ MartinBüttner Мітки необов’язкові.
DJgamer98

Чи завжди гонка і клас завжди будуть по одному слову?
Мартін Ендер

@ MartinBüttner Деякі раси та класи - це два слова, наприклад, Vine Stalker, Abyssal Knight та Deep Elf.
DJgamer98

2
Чи є специфікація цього формату файлу в морзі, або лише ці приклади?
Paŭlo Ebermann

Відповіді:


3

Perl, 151 байт

148 код + 3 вимикача ( -0, -l, -p). Я впевнений, що це можна покращити :)

Бере вхід з STDIN і друкує результат при отриманні 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]'

Безголівки:

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


3

F #, 377 байт

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

3

Javascript (ES6), 297 230 байт

Наразі це регулярний вираз, керований тестом.

Він просто замінює небажану інформацію та зберігає важливі речі.

Він створює анонімну функцію, яка просто повертає потрібний текст.

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

Хіба це не звір?


Дякуємо за підказку sysreq про те, що етикетки необов’язкові. Це врятувало мене 67 байт !


Ви можете перевірити результат вираження на: https://regex101.com/r/zY0sQ0/1


Мітки необов’язкові; ви можете зберегти досить багато байт, опустивши їх.
кіт

1
@sysreq Що ...?
Ісмаїл Мігель


2
Я кажу _=>_.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} ?)?/,' '), що це прийнятне рішення всього в 230 байтах
кішка

1
@sysreq Вибачте за те, що я так довго говорив. Я бачив пост, але я був на планшеті. Ви поняття не маєте, як боляче робити щось у планшеті. Я замінив свій код на вашу версію без ярликів. Дякую за пораду.
Ісмаїл Мігель

2

Python3, 472 байти

Я думав, що зможу отримати це набагато коротше. Не дивно, що я переміг власне уявлення. Виконайте це як 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))

2

Ідіть, 589 502 489 487 байт

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

після запуску go fmt, go fixі go vetось "невольф" версія:

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

Редагувати: використання точкового імпорту дуже допомагає.

Досить зрозуміло, але я можу пояснити, якщо це буде потрібно. Це моя перша "справжня" програма Go, і я все ще є початківець у кодегольфі, тому поради вітаються!

Редагувати: ви сказали "взяти файл із STDIN", і ви можете запустити цей скрипт (якщо він встановлений), запустивши, go install <foldername>а потім <binaryname> morgue-file.txtабоgo run main.go morgue.txt

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