Dungeon cuộn và xúc xắc rồng


20

Tôi muốn chơi Dungeon và Dragons, nhưng tôi không có xúc xắc! Thử thách của bạn là tung một vài viên xí ngầu D & D.

Đặc tả định dạng đầu vào ở dạng Backus-Naur là:

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

Số nguyên tùy chọn trước dsố là xúc xắc để cuộn; ít nhất nó phải được 1mặc định và mặc định 1nếu không được cung cấp.

Số nguyên cần thiết ngay sau số dlà mỗi cạnh của mỗi khuôn; nó phải có ít nhất 1. Các cạnh của mỗi khuôn là các số nguyên dương liên tiếp khác nhau bắt đầu từ 1.

Công cụ sửa đổi tùy chọn có thể +0và mặc định +0nếu không được chỉ định.

Ví dụ: đối với đầu vào 2d10+5, bạn tạo hai số ngẫu nhiên từ 1 đến 10, bao gồm chúng và cộng 5. Sau đó, bạn sẽ xuất kết quả.

Nếu bạn nhận đầu vào không hợp lệ, chẳng hạn như 2d, d20+, 0d4, 2d5+1+2, 2+2, hoặc bất cứ điều gì khác mà không phù hợp với định dạng này, bạn phải đầu ra " Invalid input". Mặt khác, bạn phải chỉ xuất một số nguyên ngẫu nhiên duy nhất, có trọng số theo đầu vào. Ví dụ, 3d6nên tạo ra nhiều 10s hơn 4s .

Các trường hợp thử nghiệm

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

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ giành chiến thắng!


1
02d05+073một đầu vào hợp lệ?
MT0

2
Phần khó của câu hỏi này là xác nhận đầu vào, nhưng đoạn mô tả các quy tắc xác thực là tự mâu thuẫn. Nó mô tả nplà tùy chọn, nhưng đầu vào chọn không bao gồm chúng ( d20+) là không hợp lệ.
Peter Taylor

1
@PeterTaylor: Tôi nghĩ rằng +chỉ nên thêm dấu hiệu nếu công cụ sửa đổi pđược cung cấp.
Chương trìnhFOX

4
@Doorknob, Chà, bởi vì d13 và d17 không được sử dụng xúc xắc trong D & D. D & D sử dụng d4, d6, d8, d10, d12 và d20. Ngoài ra, chắc chắn có trường hợp một cuộn sẽ bao gồm các loại xúc xắc khác nhau (ví dụ, 1d4+1d6đối với một Rogue lén tấn công bằng dao găm) hoặc có một tiêu cực p(ví dụ, 1d20-1để kiểm tra kỹ năng không có cấp bậc / huấn luyện và sửa đổi khả năng tiêu cực).
Brian S

2
Bạn sẽ chơi dnd mà không có usecase 2d8 + 1d6 + 4? Bạn sẽ có một thời gian tồi tệ
corsiKa

Câu trả lời:


12

Perl, 109 95 93 96 89 byte

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

Yêu cầu -pchuyển đổi, chiếm hai trong số các byte. Hãy thử trực tuyến trên Ideone .

Làm thế nào nó hoạt động

  • Do -pchuyển đổi, một dòng được đọc từ STDIN và được lưu trữ trong $_.

  • Lệnh s/^d/1d/prepends một 1 tới $_nếu nó bắt đầu với một d , tức là, nếu số xúc xắc chưa được xác định.

  • Biểu thức chính quy /^(\d+)d(\d+)(\+\d+)?/kiểm tra nếu dòng bao gồm một số, một chữ d , một số khác và, tùy ý, một số thứ ba đứng trước dấu + .

    Nếu có một trận đấu, các con số sẽ được lưu trong $1, $2$3.

    Trong trường hợp này, đầu vào sẽ hợp lệ khi và chỉ khi $1$2cả hai đều dương.

  • $d += 1 + rand $2 | 0thêm một số nguyên giả được chọn ngẫu nhiên từ 1 vào số cạnh được chỉ định vào $d(ban đầu được coi là 0).

  • for 1 .. $1 thực hiện như trên một lần cho mỗi số nguyên từ 1 đến số xúc xắc.

  • Lệnh $_ = $1 * $2 ? $d + $3 : 'Invalid input'thực hiện như sau:

    • Nếu $1 * $2bằng 0, nó đặt $_thành đầu vào Không hợp lệ .

    • Mặt khác, đầu vào là hợp lệ và nó được đặt $_thành tổng của các cuộn súc sắc và công cụ sửa đổi.

  • -pchuyển đổi, Perl in nội dung của $_.

  • Vì không có thêm dòng đầu vào, tập lệnh thoát.


1
Tôi tin rằng, nói chung, các tham số dòng lệnh bổ sung được coi là có giá trị một byte mỗi nhưng dấu gạch nối là miễn phí. Trong trường hợp này, bạn -psẽ chỉ mất một chi phí, biến đây thành một giải pháp 108 byte.
undergroundmonorail

2
Có thể được thực hiện 96 ký tự,/^([1-9]\d*)?d([1-9]\d*)(\+\d+)?$/||die"Invalid input$/";$a+=1+int rand$2for(1..$1||1);$_=$a+$3
Hasturkun

1
@undergroundmonorail: Tôi đã thấy mọi người đếm một chuyển đổi dòng lệnh đơn lẻ là một, hai và thậm chí ba (đếm khoảng trắng) byte. Tôi thà tính nó là một, nhưng hai byte có vẻ công bằng với tôi.
Dennis

1
@Vynce Tôi giả sử bạn không có. Tôi sử dụng |0để chuyển sang int, vì randtrả về một float giả được chọn ngẫu nhiên .
Dennis

1
@Vynce Tôi đã thêm một permalink cho câu hỏi ( ideone.com/gLJfhO ). -esẽ có vấn đề ở đây, trừ khi bạn thay thế dấu ngoặc đơn bằng dấu ngoặc kép.
Dennis

4

Pháo đài: 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;

Lạm dụng gõ ngầm ( i-ntất cả đều là số nguyên, mọi thứ khác là có thật). Thông báo trước nhỏ: đầu vào phải được phân tách không gian, do đó 2d10+5phải được nhập dưới dạng 2 d 10 + 5, nếu không bạn sẽ nhận được input conversion error.


4

Ruby, 116

Phiên bản Ruby thay thế. Tôi đã cố gắng tìm cách để làm điều đó mà không có các biểu thức thông thường, nhưng việc xác nhận bạn phải làm khó hơn rất nhiều nếu không có chúng.

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

Đây là 112, sử dụng thuật toán Perl thông minh của Dennis:

$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 Cảm ơn! Tôi không biết tại sao tôi nghĩ nó phải> 0.
Paul Prestidge

3

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

Không thể chơi golf tốt hơn thế này. Đã đến lúc trở lại làm việc.


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)chỉ có 137 byte.
Dennis

2
Theo các ý kiến ​​về câu hỏi, đây là một câu trả lời không chính xác vì nó từ chối đầu vào 02d05+073.
Peter Taylor

3

GolfScript ( 120 106 byte)

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

Đây không chỉ ngắn hơn phiên bản đầu tiên, mà còn thanh lịch hơn. Phần thực sự làm cán lăn là

\{rand)+}+@*

Phần còn lại chủ yếu là xác nhận đầu vào và một vài ký tự để phân tích cú pháp.

# 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

Bản demo trực tuyến với khung kiểm tra


Tôi đang tự hỏi tại sao bạn không sử dụng n./? Có lẽ cũng 10,n*cho một nhân vật ít hơn.
Howard

@Howard, lần đầu tiên, bởi vì đây là lần hack cuối cùng để vượt qua một số trường hợp thử nghiệm và tôi đã không nghĩ về việc chơi golf. Đến lần thứ hai, điều đó sẽ khiến nó chấp nhận một số đầu vào không hợp lệ.
Peter Taylor

2

J - 130 (45?)

Thách thức này có vẻ hơi thiên vị đối với các biểu thức thông thường, đặc biệt là phải phân biệt đầu vào không hợp lệ. J có thư viện regex POSIX, vì vậy nó không tệ, nhưng nó không được tích hợp như với Perl, vì vậy J không thể tốt hơn các ngôn ngữ khác.

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

Nếu bạn chỉ thực hiện logic cho các biểu thức hợp lệ, như các giải pháp Python / PHP xuất hiện, thì đó là 45 ký tự hợp lý hơn:

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

Các bit đáng chú ý:

  • 1!:1]1là đầu vào và (rxmatch rxfrom])là logic trả về kết quả phụ.

  • Việc đầu vào có hợp pháp hay không được xử lý bằng cách khớp regex, vì vậy chúng ta có thể đặt mặc định cho n và p với 0 1 1>.. Nó nhìn về phía sau (n là 1 theo mặc định và p là 0) vì chúng ta phải đảo ngược (|. ) danh sách trước đó, để logic ở cuối thực hiện theo đúng thứ tự.

  • @.sự kết hợp của Chương trình nghị sự , về cơ bản là một tuyên bố chuyển đổi J-ish. Nếu các kết quả trống (nếu 0 là e.uity của $ hape :) 0 e.$, chúng tôi sẽ phát ra thông báo lỗi, chúng tôi sẽ thực hiện với việc gieo xúc xắc: #~để đặt xúc xắc, 1+?lăn và +/@,thêm công cụ sửa đổi p và tổng hợp.


Cái đó có hiệu quả 01d01+01không?
Cees Timmerman

@CeesTimmerman Xấu của tôi. Nó làm ngay bây giờ.
thuật toán

2

TinyMUSH , 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)

Bốn dòng đầu tiên liên quan đến thực tế rằng "d" là bí danh cho lối ra "xuống" phổ quát với thông báo lỗi tích hợp khi nó không tồn tại; lối thoát được quét trước các lệnh do người dùng xác định. Các dòng còn lại tạo một đối tượng với lệnh do người dùng định nghĩa sử dụng hàm die () tích hợp.


2

PHP, 129

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

Sử dụng biểu thức chính quy để tạo biểu thức mà PHP sau đó đánh giá. Đầu vào được cung cấp qua url :? 0 = đối số . Hãy chắc chắn rằng bạn urlencode + đến% 2b. Đây là những gì nó trông giống như ở dạng dễ đọc hơn:

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

Việc đảo ngược các chuỗi bằng cách sử dụng ~không chỉ lưu một ký tự vì bạn không cần dấu ngoặc kép (PHP giả sử chúng là các chuỗi) mà còn lưu các ký tự vì bạn không phải thoát các dấu gạch chéo ngược trong biểu thức thông thường.

Các ?:nhà điều hành là một hình thức đặc biệt của các nhà điều hành ternary. $foo = $a ? $a : $bcũng giống như $foo = $a ?: $b.


1

Java, 378

Chỉ muốn thử một giải pháp với Java từ xa giải pháp tốt nhất. Nhưng này: Java không phải là ngôn ngữ chơi gôn trong mọi trường hợp!

Nó nhận đầu vào từ dòng lệnh. Tham số đầu tiên args[0]là giá trị đầu vào.

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

Bạn có biết, đó decodelà ngắn hơn valueOf?


1

Python 3, 184 byte

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)

Vượt qua tất cả các bài kiểm tra. Nếu xúc xắc bằng không được cho phép, nó sẽ ngắn hơn 6 byte bằng cách bỏ đi (or q).


Tôi đã hiểu nhầm BNF. Trang này giúp.
Cees Timmerman

Vì lợi ích của bất kỳ ai khác, người thắc mắc tại sao regex lại được neo ở một đầu mà không phải ở đầu kia: Python re.matchhoàn toàn neo ở đầu nhưng không ở cuối. Tôi không biết bất kỳ thư viện regex nào khác làm điều đó.
Peter Taylor

1
Có một khoản tiết kiệm nhỏ bằng cách khởi tạo t=int(c or 0); và có thể kết hợp câu trả lời của bạn với câu hỏi Python hiện có (sử dụng ít khoảng trắng hơn) để tiết kiệm thêm một vài chi tiết.
Peter Taylor

0

JavaScript 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')

Điều này rất giống với câu trả lời của Snack
user12205

Vâng, có những điểm tương đồng, đây là cùng một ngôn ngữ / thuật toán ... Nhưng tôi nghĩ có đủ sự khác biệt trong mã của tôi (và regex) để đăng một câu trả lời khác.
Michael M.

Theo các ý kiến ​​về câu hỏi, đây là một câu trả lời không chính xác vì nó từ chối đầu vào 02d05+073.
Peter Taylor

0

Hồng ngọc, 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

Sử dụng một regrec để làm tất cả các công việc. Kể từ khi tôi đang sử dụng \d+, điều duy nhất tôi cần phải kiểm tra đầu vào không hợp lệ là rằng có một trận đấu, rằng không phải nvà cũng không mđược 0, và rằng có một m. Nếu bất kỳ trong số đó được tìm thấy, nó sẽ hủy bỏ với một thông báo ( 'Invalid input'). Sau đó, nó chỉ in kết quả, vì bây giờ nó sẽ bị hủy nếu đầu vào không hợp lệ.

Việc in kết quả không thú vị lắm, nhưng ...

([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)

Sau này tôi đổi .inject(:+)thành eval(...*?+), nhưng ý tưởng là như vậy.


0

Python3, 204B

Mine nhịp đập câu trả lời Python hiện bằng cách thêm trong việc xử lý lỗi cần thiết và đọc d20như 1d20hơn 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)

chỉnh sửa để sửa 2 lỗi chính tả : I(x) => I(c),Invalid Input => Invalid input

chỉnh sửa để sửa regex: \+?(\d*) => (\+\d+)?


Theo câu hỏi được làm rõ, đây là một câu trả lời không chính xác vì nó chấp nhận đầu vào 3d20+.
Peter Taylor

Điểm tốt! #filler
alexander-brett

Và không 01d01+01.
Cees Timmerman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.