롤 던전과 드래곤 주사위


20

던전과 드래곤을하고 싶지만 주사위가 없습니다! 당신의 도전은 일부 D & D 주사위를 굴리는 것입니다.

Backus-Naur 형식의 입력 형식 사양 은 다음과 같습니다.

<valid-input>  ::= <opt-integer> "d" <integer> <opt-modifier>
<opt-integer>  ::= | <integer>
<opt-modifier> ::= | "+" <integer>
<integer>      ::= "0" | "1" | "2" | "3" | "4" | "5" |
                   "6" | "7" | "8" | "9" | <integer> <integer>

앞에있는 선택적인 정수 d는 굴릴 주사위의 수입니다. 최소한이어야하며 제공되지 않은 경우 1기본값으로 설정 1됩니다.

바로 뒤에 필요한 정수 d는 각 다이의 변의 수입니다. 최소한이어야합니다 1. 각 다이의 변은에서 시작하는 별개의 연속적인 양의 정수 1입니다.

선택적 수정자는 일 수 있으며 지정되지 않은 경우 +0기본값이 +0사용됩니다.

예를 들어 input의 2d10+5경우 1에서 10까지의 두 개의 난수를 생성하고 함께 더한 다음 5를 더합니다. 그러면 결과가 출력됩니다.

당신은 잘못된 입력과 같은받은 경우 2d, d20+, 0d4, 2d5+1+2, 2+2, 당신이 "출력해야이 형식에 맞지 않는 사람, 또는 아무것도 Invalid input"를. 그렇지 않으면 입력에 따라 가중치가 부여 된 단일 임의의 정수만 출력해야합니다. 예를 들어, 3d6더 생산한다 10초 이상 4 .

테스트 사례

Input      Minimum possible output    Maximum possible output
d1         1                          1
d6         1                          6
d1+3       4                          4
d20+3      4                          23
2d1        2                          2
2d6+2      4                          14
d01        1                          1
d01+0      1                          1
01d01+01   2                          2
3d20+10    13                         70

d          Invalid input
d0         Invalid input
d+0        Invalid input
d0+0       Invalid input
0d1        Invalid input
0d1+1      Invalid input
d1+        Invalid input
1d         Invalid input
1d1+       Invalid input
1d+1       Invalid input
2d+2d      Invalid input
d2+d2      Invalid input
d2+2+2     Invalid input
d2-1       Invalid input
-d2        Invalid input
-2d2       Invalid input
4*3        Invalid input
4*d2       Invalid input

이것은 이므로 바이트 단위의 가장 짧은 코드가 이길 것입니다!


1
02d05+073유효한 입력은?
MT0

2
이 질문에 대한 어려운 부분은 입력의 유효성을 검사하는 것이지만 유효성 검사 규칙을 설명하는 단락은 자체 모순됩니다. 설명 np선택 사항이지만 d20+유효하지 않은 것으로 포함하도록 선택하는 입력입니다 ( ).
피터 테일러

1
@ PeterTaylor : +수정자가 p제공된 경우에만 부호를 추가해야 한다고 생각합니다 .
ProgramFOX

4
@Doorknob, d13과 d17은 D & D에 주사위가 사용되지 않기 때문입니다. D & D는 d4, d6, d8, d10, d12 및 d20을 사용합니다. 또한 롤에 다른 유형의 주사위 (예 : 1d4+1d6단검으로 도둑 몰래 공격하는 경우) 또는 음수 p(예 : 1d20-1순위 / 훈련이없는 스킬 검사 및 음수 능력 수정 자)가있는 경우가 있습니다.
Brian S

2
당신은 유스 케이스없이 dnd를 할 것입니다 2d8 + 1d6 + 4. 당신은 나쁜 시간을 가질거야
corsiKa

답변:


12

Perl, 109 95 93 96 89 바이트

s/^d/1d/;/^(\d+)d(\d+)(\+\d+)?$/;$d+=1+rand$2|0for
1..$1;$_=$1*$2?$d+$3:'Invalid input'

-p2 바이트를 차지하는 스위치가 필요합니다 . Ideone에서 온라인으로 사용해보십시오 .

작동 원리

  • -p스위치로 인해 STDIN에서 행을 읽고에 저장됩니다 $_.

  • 이 명령 은 d로 시작 하는 경우 ( 즉, 주사위 수가 지정되지 않은 경우)에 1s/^d/1d/추가 합니다.$_

  • 정규식 /^(\d+)d(\d+)(\+\d+)?/은 행이 숫자, 리터럴 d , 다른 숫자 및 선택적으로 + 기호 앞에 오는 세 번째 숫자 로 구성되어 있는지 확인합니다 .

    일치가있는 경우 숫자는에 저장됩니다 $1, $2$3.

    이 경우, 입력이있는 경우에만 유효한 것 $1$2모두 긍정적이다.

  • $d += 1 + rand $2 | 0의사 난수로 선택된 정수를 1에서 지정된 변 수에 추가합니다 $d(처음에는 0으로 처리됨).

  • for 1 .. $1 1과 주사위 수 사이의 모든 정수에 대해 위의 작업을 한 번 수행합니다.

  • 이 명령 $_ = $1 * $2 ? $d + $3 : 'Invalid input'은 다음을 수행합니다.

    • 경우 $1 * $2제로, 그것은 설정 $_유효하지 않은 입력 .

    • 그렇지 않으면 입력이 유효하고 $_주사위 롤과 수정 자의 합으로 설정 됩니다.

  • -p스위치로 인해 Perl은의 내용을 인쇄합니다 $_.

  • 더 이상 입력 행이 없으므로 스크립트가 종료됩니다.


1
일반적으로 여분의 명령 줄 매개 변수는 각각 1 바이트의 가치가 있지만 하이픈은 무료라고 생각합니다. 이 경우 -p하나의 비용 만 지불하면 108 바이트 솔루션이됩니다.
undergroundmonorail

2
96 개의 문자를 만들 수 있음/^([1-9]\d*)?d([1-9]\d*)(\+\d+)?$/||die"Invalid input$/";$a+=1+int rand$2for(1..$1||1);$_=$a+$3
Hasturkun

1
@undergroundmonorail : 사람들이 단일 명령 줄 스위치를 1, 2 및 3 (공백 계산) 바이트로 계산하는 것을 보았습니다. 오히려 1로 계산하지만 2 바이트는 나에게 공평 해 보입니다.
Dennis

1
@Vynce 나는 당신도하지 않은 것으로 가정합니다. 의사 무작위로 선택된 float 반환하기 |0때문에 int로 캐스트하는 데 사용 합니다 . rand
Dennis

1
@Vynce 질문에 영구 링크를 추가했습니다 ( ideone.com/gLJfhO ). -e작은 따옴표를 큰 따옴표로 바꾸지 않으면 여기에서 문제가 될 수 있습니다.
Dennis

4

포트란 : 145

character(1)a;read(*,*)s,a,j,a,k;n=0;if(k<0.or.a=="-")then;print*,"error k<0";stop;endif;do l=1,int(s);n=n+int(s*rand(0)+1);enddo;print*,n+k;end;

암시 적 타이핑을 남용합니다 ( i-n모두 정수, 그 밖의 모든 것). 사소한 경고 : 입력은 공백으로 구분 2d10+5되어야하므로로 입력해야합니다 . 2 d 10 + 5그렇지 않으면을 얻습니다 input conversion error.


4

루비, 116

대체 루비 버전. 나는 정규 표현식없이 그것을 할 수있는 방법을 찾으려고했지만, 당신이해야 할 검증은 그것들이 없으면 훨씬 더 어렵습니다.

gets=~/^(\d+)?d(\d+)(\+\d+)?$/
a=$1||?1
puts$~&&a>?0?eval("r=#{$3||0};#{a}.times{r+=rand(#$2)+1};r"):'Invalid input'

이것은 Dennis의 영리한 Perl 알고리즘을 사용하여 112입니다.

$p='(\d*[1-9]\d*)'
puts~/^#$p?d#$p(\+\d+)?$/?eval("r=#{$3||0};#{$1||1}.times{r+=rand(#$2)+1};r"):'Invalid input'

@ m.buettner 감사합니다! 왜 내가> 0이어야한다고 생각했는지 모르겠습니다.
Paul Prestidge

3

자바 직원, 158

m=prompt().match(/^([1-9]\d*)?d([1-9]\d*)(\+\d+)?$/);if(!m)alert("Invalid input");else{for(s=+m[3]|0,i=0;i<(+m[1]||1);i++)s+=Math.random()*+m[2]+1|0;alert(s)}

이보다 더 나은 골프는 없습니다. 다시 일할 시간입니다.


1
s="Invalid input";if(m=prompt().match(/^([1-9]\d*)?d([1-9]\d*)(\+\d+)?$/))for(s=m[3]|0,i=0;i<(m[1]||1);i++)s+=Math.random()*m[2]+1|0;alert(s)137 바이트 만 있습니다.
Dennis

2
질문에 대한 의견에 따르면 입력을 거부하기 때문에 잘못된 답변 02d05+073입니다.
피터 테일러

3

GolfScript ( 120 106 바이트)

.100?!1`*\+.43?)!'+0'*+.10,'d+':^*-!*.10,''*-^=*^1/{/n*}/~].,3=*3,or:x~;*{x~\{rand)+}+@*}'Invalid input'if

이것은 첫 번째 버전보다 짧을뿐만 아니라 더 우아합니다. 실제로 다이 롤링을하는 부분은

\{rand)+}+@*

나머지는 주로 입력 유효성 검사이며 구문 분석을위한 몇 문자입니다.

# Start by converting valid inputs into valid inputs with all optional bits.
# Prepend a '1' if the string starts with 'd'.
.100?!1`*\+
# Append '+0' if there's no '+' in the string.
.43?)!'+0'*+
# Now we start knocking out the invalid inputs.
# If it contains a character other than [0-9d+], replace the string with ''.
.10,'d+':^*-!*
# If it doesn't contain exactly one 'd', exactly one '+', and the 'd' before the '+',
# replace the string with ''.
.10,''*-^=*
# Now we either have a valid string, an empty string, or a string which is almost valid
# but has some empty substrings which should be integers, or a forbidden 0 integer value.
# Replace the 'd' and '+' with newlines, eval the result, and gather into an array.
^1/{/n*}/~]
# If we had any empty parts, we'll have fewer than 3 items on the stack.
# In that case, replace with integer values which will fail the final validation step.
.,3=*3,or
# Final validation: number of dice * number of sides per die != 0.
:x~;*
# If we pass, do the actual die rolling. Otherwise give the error message.
{x~\{rand)+}+@*}'Invalid input'if

테스트 프레임 워크가있는 온라인 데모


왜 사용하지 않는지 궁금합니다 n./. 10,n*한 캐릭터도 적을 수도 있습니다 .
Howard

@Howard, 처음으로, 테스트 사례를 통과하는 것이 막판 해킹이었고 골프를 생각하지 않았습니다. 두 번째로, 그것은 잘못된 입력을 받아 들일 것입니다.
Peter Taylor

2

J-130 (45?) 숯

이 문제는 정규식, 특히 잘못된 입력을 구별해야하는 경우에 약간 편향되어 있습니다. J는 POSIX 정규식 라이브러리를 가지고 있으므로 그렇게 나쁘지는 않지만 Perl과 같이 통합되어 있지 않으므로 J는 다른 언어보다 나아지지 않습니다.

+/@,`(1+?@#~)/`('Invalid input'"_)@.(0 e.$)0 1 1>.".>|.}.((,'?d','(\+[0-9]+)?$',~}.)'^([0-9]*[1-9][0-9]*)')(rxmatch rxfrom])1!:1]1

Python / PHP 솔루션과 같이 유효한 식에 대한 논리를 구현하는 경우보다 합리적인 45 자입니다.

+/,(1+[:?@#/1>.".;._2@,&'d')`".;._1'+',1!:1]1

주목할만한 비트 :

  • 1!:1]1은 입력이며 (rxmatch rxfrom])하위 표현식 일치를 반환하는 논리입니다.

  • 입력이 올바른지 여부는 정규식 일치에 의해 처리되므로을 사용하여 n 및 p의 기본값을 설정할 수 있습니다 0 1 1>.. |.마지막에 논리가 올바른 순서로 실행되도록 목록을 먼저 역순으로 전환해야했기 때문에 거꾸로 보입니다 (n은 기본적으로 1이고 p는 0입니다) .

  • @.는 IS 일정 함께 본질적 J 틱 스위치 문. 일치하는 항목이 비어있는 경우 (0이 $ hape :) 인 경우 0 e.$오류 메시지가 표시됩니다. 그렇지 않으면 주사위를 굴려서 진행합니다. 주사위 #~를 설정하고 1+?구르고 +/@,수정자를 추가합니다. 그리고 합계.


그게 효과가 01d01+01있습니까?
Cees Timmerman

@CeesTimmerman 나의 나쁜. 지금은 그렇습니다.
algorithmshark

2

타이니 머시 , 239

@dig/t +
@op d=+
@lo d=d
@fail d=Invalid input
@cr .
@set .=com
&d .=$*:\ifelse(regmatch(%0,^(\\\\d+)?d(\\\\d+)(\\\\+\\\\d+)?$,0 1 2 3),ifzero(and(or(not(strlen(%q1)),%q1),%q2),Invalid input,add(die(usetrue(%q1,1),%q2),%q3)),Invalid input)

처음 네 줄은 "d"가 존재하지 않는 경우 기본 제공 실패 메시지가있는 범용 "다운"종료의 별명이라는 사실을 처리합니다. 사용자 정의 명령 전에 엑시트가 스캔됩니다. 나머지 줄은 내장 die () 함수를 사용하여 사용자 정의 명령으로 객체를 만듭니다.


2

PHP, 129

<?eval(preg_filter(~Сף›ÔÖÀ›×£›Ö×£Ô£›ÔÖÀÛÐ,~ÛžÂÝÛÎÝÀÅÎÄ™×ÄÛ–ÔÔÃÛžÄیԞ‘›×ÎÓÛÍÖÖÄšœ—ÛŒÛÌÄ,$_GET[0])?:~šœ—ݶ‘‰ž“–›ß–‘Š‹ÝÄ);

정규식을 사용하여 PHP가 평가하는 표현식을 만듭니다. URL을 통해 입력이 공급됩니다.? 0 = argument . +를 % 2b (으)로 urlencode해야합니다. 보다 읽기 쉬운 형태로 다음과 같이 나타납니다.

eval(preg_filter('/^(\\d)?d(\\d)(\\+\\d)?$/','$a="$1"?:1;for(;$i++<$a;$s+=rand(1,$2));echo$s$3;',$_GET[0])?:'echo"Invalid input";');

을 사용하여 문자열을 비트 단위로 반전하면 ~따옴표가 필요 없기 때문에 (PHP는 문자열이라고 가정) 정규 표현식에서 백 슬래시를 이스케이프 할 필요가 없으므로 문자를 저장합니다.

?:연산자는 삼항 연산자의 특별한 형태이다. $foo = $a ? $a : $b와 동일합니다 $foo = $a ?: $b.


1

자바, 378

최고의 솔루션에서 멀리 떨어진 Java로 솔루션을 시험 해보고 싶었습니다. 그러나 야 : 자바는 골프 언어가 아닙니다!

명령 행에서 입력을받습니다. 첫 번째 매개 변수 args[0]는 입력 값입니다.

class A{public static void main(String[]s){System.out.print(s[0].matches(
"(0+\\d+|[1-9]\\d*|)d(0+\\d+|[1-9]\\d*)(\\+\\d+)?")?z(s[0]):"Invalid input");}static int
z(String s){String[]a=s.split("d");String[]b=a[1].split("\\+");int c=a[0].isEmpty()?1:Byte.
decode(a[0]);int d=b.length<2?0:Byte.decode(b[1]);while(c-->0)d+=new java.util.Random().
nextInt(Byte.decode(b[0]))+1;return d;}}

당신은, 알고 계셨습니까 decode보다 짧은 valueOf?


1

파이썬 3, 184 바이트

import random,re
try:a,b,c=re.findall("^(\d*)d(\d+)(\+\d+)?$",input())[0];t=int(c or 0)+(sum(random.randint(1,int(b))for i in range(int(a or 1)))or q)
except:t="Invalid input"
print(t)

모든 테스트를 통과합니다. 제로 주사위가 허용 된 경우을 제외하면 6 바이트가 짧아집니다 (or q).


그래도 나는 BNF를 오해했다. 이 페이지가 도움 됩니다.
Cees Timmerman

왜 정규 표현식이 한쪽 끝에 고정되어 있고 다른쪽에는 고정되어 있지 않은지 궁금해하는 다른 사람들을 위해 : 파이썬 re.match은 처음에는 암시 적으로 고정 되지만 끝에는 고정 되지 않습니다. 나는 그것을하는 다른 정규식 라이브러리를 모른다.
피터 테일러

1
초기화하여 약간의 절약이 있습니다 t=int(c or 0). 그리고 더 적은 공백을 사용하는 기존 Python과 답변을 결합하여 커플을 더 절약 할 수 있습니다.
피터 테일러

0

자바 스크립트 134

m=prompt().match(/^((?!0)\d*)d((?!0)\d+)(\+\d+)?$/);alert(m?eval('for(o=m[3]|0,i=m[1]||1;i--;)o+=m[2]*Math.random()+1|0'):'Invalid input')


글쎄, 유사점이 있습니다. 이것은 같은 언어 / 알고리즘입니다 ... 그러나 다른 답변을 게시하기에 내 코드 (및 정규식)에 충분한 차이가 있다고 생각했습니다.
Michael M.

질문에 대한 의견에 따르면 입력을 거부하기 때문에 잘못된 답변 02d05+073입니다.
피터 테일러

0

루비, 167 147

/^(\d+)?d(\d+)(\+\d+)?$/.match gets
abort'Invalid input'if !$~||$1==?0||!$2||$2==?0
p eval(([0]*($1||1).to_i).map{rand($2.to_i)+1}*?+)+($3||0).to_i

정규식을 사용하여 모든 작업을 수행하십시오. 내가 사용하고 있기 때문에 \d+, 내가 잘못된 입력을 확인해야 할 유일한 일이 둘 것을 일치가 있다고되어 nm없었다 0가, 그리고 것을 m. 이 중 하나라도 발견되면 메시지 ( 'Invalid input') 와 함께 중단됩니다 . 그런 다음 입력이 유효하지 않으면 지금 중단되었으므로 결과를 인쇄합니다.

결과 인쇄는 그리 재미 있지 않지만 ...

([0]*($1||1).to_i)    # create an array of n elements (1 if there is no n)
.map{rand($2.to_i)+1} # fill it up with random numbers, where the number x is 1 < x < m+1
.inject(:+)           # add them all up
+($3||0).to_i         # and finally add the modifier (0 if there is none)

나중에 변경 .inject(:+)eval(...*?+)있지만, 아이디어는 동일합니다.


0

파이썬 3, 204B

Mine은 필요한 오류 처리 및 읽기 d20를 추가 1d20하지 않고 기존 Python 답변을 능가합니다. 0d20:)

import random,re
try:a,b,c=re.findall('^([1-9]\d*)?d(\d+)(\+\d+)?$',input())[0];I=int;R=sum(random.randrange(I(b))+1for x in[0]*(1if a==''else I(a)))+(0if c==''else I(c))
except:R='Invalid input'
print(R)

2 오타를 수정하도록 수정되었습니다. I(x) => I(c),Invalid Input => Invalid input

정규식을 수정하기 위해 편집 : \+?(\d*) => (\+\d+)?


명확한 질문에 따르면, 이것은 input을 수락하기 때문에 오답 3d20+입니다.
Peter Taylor

좋은 지적! #filler
alexander-brett

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