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:하거나 한 줄에 하나씩 동일한 순서로 정보를 출력하기에 충분합니까?
Martin Ender

@ MartinBüttner 레이블은 선택 사항입니다.
DJgamer98

종족과 클래스는 항상 각각 한 단어입니까?
마틴 엔더

@ MartinBüttner Vine Stalker, Abyssal Knight 및 Deep Elf와 같은 일부 종족 및 클래스는 두 단어입니다.
DJgamer98

2
이 영안실 파일 형식의 사양이 있습니까, 아니면이 예제 만 있습니까?
Paŭlo Ebermann

답변:


3

펄, 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

자바 스크립트 (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 에서 resulgar 식을 테스트 할 수 있습니다.


레이블은 선택 사항입니다. 생략하면 꽤 많은 바이트를 절약 할 수 있습니다.
고양이

1
@sysreq 무엇 ...?
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} ?)?/,' ')단지 230 바이트에서 허용되는 해결책 이라고 말하고있다.
cat

1
@sysreq 아무 말도하지 않아서 죄송합니다. 게시물을보고 있었지만 태블릿에있었습니다. 태블릿에서 무언가를하는 것이 얼마나 고통 스러운지 전혀 모른다. 코드를 라벨이없는 버전으로 교체했습니다. 팁 주셔서 감사합니다.
Ismael Miguel

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여기에 "ungolfed"버전입니다 :

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

편집 : 도트 가져 오기를 사용하면 많은 도움이됩니다.

설명이 필요하지만 필요한 경우 설명 할 수 있습니다. 이것은 나의 첫 번째 '진짜'바둑 프로그램이며 여전히 codegolf의 초보자이므로 팁을 환영합니다!

편집 : 당신이 실행 (이 경우 설치 가서) "STDIN에서 파일을", 당신은이 스크립트를 실행할 수 있습니다 말했다 go install <foldername>다음과 <binaryname> morgue-file.txtgo run main.go morgue.txt

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.