DCSS morg dosya ayrıştırıcı


9

Bu meydan okumada, roguelike oyunu Dungeon Crawl Stone Soup'tan morg dosyalarını ayrıştırmanız ve STDOUT'a çıkarmanız gerekir .

Bu morg dosyaları nedir ??

Öldüğünüzde, o karakterin içindeki verilerle bir metin dosyası oluşturulur. Karakterin sahip olduğu ekipmanları, son birkaç turda neler olduğunu ve kaç canavarı öldürdüğünü görebilirsiniz.

Burada bir örnek morg dosyası bulabilirsiniz

Meydan okuma

İşiniz bu dosyalardan birini STDIN'den alan, ayrıştıran ve verileri STDOUT'a veren bir program yapmaktır.

Bu zorluğu biraz daha kolaylaştırmak için, sadece metnin ilk bloğunu ayrıştırmanız gerekir. (kadar kadarThe game lasted <time> (<turns> turns).

Aşağıdaki bilgileri ayrıştırmanız ve çıktısını almanız gerekir:

  • Sürüm numarası.
  • Puan.
  • Karakter adı, unvanı, ırkı ve sınıfı.
  • Karakter seviyesi.
  • Ölüm / zafer nedeni.
  • Koşunun sürdüğü dönüş miktarı.

Misal:

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

Test Durumları

Test örneği 1 - Zafer

Giriş dosyası

Örnek çıktı - Zafer:

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

Test örneği 2 - Ölüm

Giriş dosyası

Örnek çıktı - Ölüm:

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

kurallar

  • Bu böylece en kısa kod kazanır.
  • Beraberlik durumunda en eski cevap kazanır.
  • Standart boşluklar yok.
  • Dosya girişi STDIN'den alınmalıdır
  • Çıktı STDOUT'a gönderilmelidir
  • Çıktıdan önceki etiketler (ör. Turns:) İsteğe bağlıdır.

İlham almak için hareketsiz örnek kod

DCSS'de morg dosya oluşturma kodu


Çıktının aslında Version:bilgi parçalarını aynı sırada, her satıra bir tane çıkarmak için yeterli veya yeterli satır etiketleri içermesi gerekiyor mu?
Martin Ender

@ MartinBüttner Etiketler isteğe bağlıdır.
DJgamer98

Irk ve sınıf her zaman birer kelime olacak mı?
Martin Ender

@ MartinBüttner Bazı yarışlar ve sınıflar Vine Stalker, Abyssal Knight ve Deep Elf gibi iki kelimedir.
DJgamer98

2
Bu morg dosya biçiminin spesifikasyonu var mı, yoksa yalnızca bu örnekler var mı?
Paŭlo Ebermann

Yanıtlar:


3

Perl, 151 bayt

148 kod + 3 anahtar ( -0, -l, -p). Eminim bu geliştirilebilir :)

STDIN'den girdi alır ve EOF alımında sonucu yazdırır.

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


3

F #, 377 bayt

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 bayt

Şimdilik, bu test odaklı bir düzenli ifadedir.

Sadece istenmeyen bilgileri değiştirir ve önemli şeyleri tutar.

İstenilen metni döndüren anonim bir işlev oluşturur.

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

Bu bir canavar değil mi?


Etiketlerin isteğe bağlı olduğu konusunda sysreq'in ipucu için teşekkürler . Bu beni 67 bayt kurtardı !


Resulgar ifadesini şu adresten test edebilirsiniz: https://regex101.com/r/zY0sQ0/1


Etiketler isteğe bağlıdır; bunları atlayarak birkaç bayt kaydedebilirsiniz.
kedi

1
@sysreq Neyi ...?
Ismael Miguel


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} ?)?/,' ')Sadece 230
cat

1
@sysreq Bir şey söylemenin çok uzun sürdüğü için üzgünüm. Gönderiyi görüyordum ama tabletteydim. Bir tablette herhangi bir şey yapmanın ne kadar acı verici olduğu hakkında hiçbir fikriniz yok. Kodumu etiketsiz sürümünüzle değiştirdim. Bahşiş için çok teşekkürler.
Ismael Miguel

2

Python3, 472 bayt

Bunu daha da kısaltabileceğimi düşündüm. Yine de kendi teslimimi yenerek şaşırmadım. Gibi çalıştırın 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

Git 589 502 489 487 bayt

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

çalıştırdıktan sonra go fmt, go fixve go vetburada "ungolfed" versiyonu:

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

Düzenleme: nokta-ithalatı kullanmak çok yardımcı olur.

Oldukça açıklayıcı ama gerekirse açıklayabilirim. Bu benim ilk 'gerçek' Git programım ve hala ipuçları hoş geldiniz, bu yüzden ipuçları hoş geldiniz!

Düzenleme: Eğer çalıştırarak (eğer varsa yüklü go) "STDIN'den bir dosyayı almak" ve bu komut dosyasını çalıştırabilirsiniz söyledi go install <foldername>sonra ve <binaryname> morgue-file.txtyago run main.go morgue.txt

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.