Quero jogar Dungeons and Dragons, mas não tenho dados! Seu desafio é rolar alguns dados de D&D.
A especificação do formato de entrada no formato 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>
O número inteiro opcional antes de d
é o número de dados a serem lançados; deve ser pelo menos 1
e o padrão é 1
se não for fornecido.
O número inteiro necessário imediatamente após o d
é o número de lados que cada dado possui; deve ser pelo menos 1
. Os lados de cada dado são números inteiros positivos consecutivos distintos começando em 1
.
O modificador opcional pode ser +0
e o padrão é +0
se não for especificado.
Por exemplo, para a entrada 2d10+5
, você gera dois números aleatórios de 1 a 10 inclusive, os soma e adiciona 5. Em seguida, você produzirá o resultado.
Se você receber uma entrada inválida, como 2d
, d20+
, 0d4
, 2d5+1+2
, 2+2
, ou qualquer outra coisa que não se encaixa neste formato, você deve saída " Invalid input
". Caso contrário, você deve gerar apenas um único número inteiro aleatório, ponderado de acordo com a entrada. Por exemplo, 3d6
deve produzir mais 10
s do que4
s .
Casos de teste
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
Isso é código-golfe , então o código mais curto em bytes vencerá!
02d05+073
uma entrada válida?n
ep
como opcional, mas a entrada que escolhe não incluí-los (d20+
) como inválidos.+
sinal só deve ser adicionado se o modificadorp
for fornecido.1d4+1d6
para uma invasão desonesta atacar com uma adaga) ou ter um resultado negativop
(por exemplo,1d20-1
para uma verificação de habilidades sem classificações / treinamento e um modificador de habilidades negativo).2d8 + 1d6 + 4
? Você vai ter um mau tempoRespostas:
Perl,
10995939689 bytesRequer a
-p
opção, que responde por dois dos bytes. Experimente online no Ideone .Como funciona
Por causa da
-p
opção, uma linha é lida em STDIN e armazenada em$_
.O comando
s/^d/1d/
anexa um 1 para$_
se começar com um d , isto é, se o número de dados não tiver sido especificado.A expressão regular
/^(\d+)d(\d+)(\+\d+)?/
verifica se a linha consiste em um número, um literal d , outro número e, opcionalmente, um terceiro número precedido por um sinal de + .Se houver uma correspondência, os números serão salvos em
$1
,$2
e$3
.Nesse caso, a entrada será válida se e somente se
$1
e$2
forem ambas positivas.$d += 1 + rand $2 | 0
adiciona um número inteiro escolhido pseudo-aleatoriamente de 1 ao número especificado de lados de$d
(inicialmente tratado como zero).for 1 .. $1
faz o acima uma vez para cada número inteiro entre 1 e o número de dados.O comando
$_ = $1 * $2 ? $d + $3 : 'Invalid input'
faz o seguinte:Se
$1 * $2
for zero, ele define$_
como Entrada inválida .Caso contrário, a entrada é válida e é definida
$_
como a soma dos dados e do modificador.Por causa da
-p
opção, Perl imprime o conteúdo de$_
.Como não há mais linhas de entrada, o script é encerrado.
fonte
-p
custaria apenas um, tornando esta uma solução de 108 bytes./^([1-9]\d*)?d([1-9]\d*)(\+\d+)?$/||die"Invalid input$/";$a+=1+int rand$2for(1..$1||1);$_=$a+$3
|0
para converter para int, poisrand
retorna um float pseudo-aleatoriamente escolhido .-e
seria problemático aqui, a menos que você substitua as aspas simples por aspas duplas.Fortran: 145
Abusa de digitação implícita (
i-n
todos são inteiros, todo o resto é real). Advertência menor: a entrada deve ser separada por espaço, portanto2d10+5
deve ser inserida como2 d 10 + 5
, caso contrário, você receberá uminput conversion error
.fonte
Ruby, 116
Versão alternativa do Ruby. Eu estava tentando encontrar uma maneira de fazer isso sem as expressões regulares, mas a validação que você precisa fazer é muito mais difícil sem elas.
Este é o 112, usando o inteligente algoritmo Perl de Dennis:
fonte
Javascipt, 158
Não é possível jogar golfe melhor que isso. É hora de voltar ao trabalho.
fonte
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)
possui apenas 137 bytes.02d05+073
.GolfScript (
120106 bytes)Isso não é apenas mais curto que a primeira versão, mas também mais elegante. A parte que realmente faz o rolamento é:
O restante é principalmente validação de entrada e alguns caracteres para análise.
Demonstração online com estrutura de teste
fonte
n./
? Talvez também10,n*
para um personagem a menos.J - 130 (45?) Char
Esse desafio parece ser um pouco tendencioso em relação a expressões regulares, principalmente por ter que diferenciar entradas inválidas. J possui uma biblioteca de expressões regulares POSIX, portanto não é tão ruim, mas não está integrada como é com Perl, portanto, J não se sai melhor do que outras linguagens.
Se você está apenas implementando a lógica para expressões válidas, como as soluções Python / PHP parecem, são os 45 caracteres mais razoáveis:
Bits notáveis:
1!:1]1
é a entrada e(rxmatch rxfrom])
é a lógica que retorna as correspondências da subexpressão.Se a entrada é legal ou não é tratada pela correspondência de regex, para que possamos definir os padrões para n e p com
0 1 1>.
. Ele olha para trás (n é 1 por padrão ep é 0) porque tivemos que inverter (|.
) a lista anteriormente, para que a lógica no final seja executada na ordem correta.@.
é a conjunção da Agenda , essencialmente uma declaração J-ish switch. Se os jogos estão vazias (se 0 é um e.lement dos US $ hape:0 e.$
), que emitem a mensagem de erro, o mais que passar com rolando os dados:#~
para definir os dados,1+?
de rolo, e+/@,
para adicionar o p modificador e soma.fonte
01d01+01
?TinyMUSH , 239
As quatro primeiras linhas tratam do fato de que "d" é um alias para a saída "inativa" universal com uma mensagem de falha interna quando ela não existe; as saídas são varridas antes dos comandos definidos pelo usuário. As linhas restantes criam um objeto com um comando definido pelo usuário, utilizando a função die () interna.
fonte
PHP, 129
Usa um regex para criar uma expressão que o PHP avalia. A entrada é alimentada via url:? 0 = argumento . Certifique-se de codificar o + para% 2b. Aqui está o que parece de uma forma mais legível:
A inversão de bits em bits usando
~
não apenas salva um caractere porque você não precisa de aspas (o PHP assume que são cadeias), mas também salva caracteres porque não é necessário escapar das barras invertidas na expressão regular.O
?:
operador é uma forma especial do operador ternário.$foo = $a ? $a : $b
é o mesmo que$foo = $a ?: $b
.fonte
Java, 378
Só queria tentar uma solução com Java longe da melhor solução. Mas ei: Java não é uma linguagem de golfe em qualquer caso!
Obtém a entrada da linha de comando. O primeiro parâmetro
args[0]
é o valor de entrada.Você sabia que isso
decode
é mais curto quevalueOf
?fonte
Python 3, 184 bytes
Passa em todos os testes. Se zero dado fosse permitido, seriam 6 bytes mais curtos deixando de fora
(or q)
.fonte
re.match
ancora implicitamente no início, mas não no final. Não conheço nenhuma outra biblioteca regex que faça isso.t=int(c or 0)
; e pode ser possível combinar sua resposta com a existente do Python (que usa menos espaço em branco) para economizar mais alguns.JavaScript 134
fonte
02d05+073
.Ruby,
167147Usa uma regexp para fazer todo o trabalho. Desde que eu estou usando
\d+
, as únicas coisas que eu preciso para verificar se há uma entrada inválida são de que houve uma partida, que nemn
, nemm
foram0
, e que havia umam
. Se algum desses for encontrado, ele será abortado com uma mensagem ('Invalid input'
). Em seguida, apenas imprime o resultado, pois já teria sido abortado se a entrada fosse inválida.A impressão de resultados não é tão interessante, mas ...
Mais tarde mudei
.inject(:+)
paraeval(...*?+)
, mas a ideia é a mesma.fonte
Python3, 204B
O Mine supera a resposta existente do Python adicionando o tratamento e a leitura de erros necessários,
d20
em1d20
vez de0d20
:)editadas para corrigir erros de digitação 2:
I(x) => I(c)
,Invalid Input => Invalid input
editado para corrigir o regex:
\+?(\d*) => (\+\d+)?
fonte
3d20+
.01d01+01
.