Encontre o resultado de um jogo de guerra
Quando eu estava na escola primária, havia um jogo de "Pedra-Papel-Tesoura" que brincávamos durante as assembléias, enquanto aguardávamos nosso professor, no recreio etc. Chamamos de "Guerra". Depois de algumas pesquisas, porém, verifica-se que essa é uma variante muito mais simples do "Jogo de espingarda" (de acordo com o WikiHow) . Vou chamá-lo de "Guerra", pois as regras são um pouco diferentes:
2 pessoas se sentam em frente uma da outra. O objetivo do jogo é "matar" o outro jogador. A cada turno, você pode executar um dos três movimentos:
Recarregar : Você tem uma arma que detém um único tiro. Ele deve ser recarregado antes de poder ser disparado a cada vez. Recarregar quando você já tem munição é legal, mas não faz nada. Uma recarga foi simbolizada tocando nas têmporas com as duas mãos. Cada jogador começa com 0 munição.
Guarda : O único movimento seguro. Se você é baleado enquanto guarda, você não morre. A guarda foi simbolizada cruzando os braços sobre o peito.
Fogo : Dispare sua arma. Para disparar com sucesso, você deve ter recarregado desde o último tiro. Se o seu oponente estiver recarregando, você ganha. Se eles também dispararem, e vocês dois tiverem munição, é um empate. Se eles estão guardando, você desperdiçou a munição. Embora disparar sem munição seja uma jogada legal, ele não faz nada e o deixa vulnerável como recarregar. O disparo foi simbolizado apontando para o outro jogador.
Foi jogado de forma semelhante ao RPS, em que cada jogador joga simultaneamente a sua escolha (batemos as pernas duas vezes entre turnos para manter o ritmo um com o outro, mas isso não é importante para o desafio).
O desafio:
Sua tarefa é encontrar o resultado de um jogo de guerra. Pode ser uma função ou programa completo.
Entrada
A opção que cada jogador escolheu a cada turno será representada por um personagem / sequência:
r : recarregar
g : guarda
f : fogo
A entrada será uma lista de pares, uma sequência delimitada / não delimitada ou qualquer outra coisa nesse sentido.
Um exemplo de entrada em Python poderia ser [("r", "g"), ("f", "r")]
, ou seja , no primeiro turno, o primeiro jogador recarregou e o segundo jogador guardou. No segundo turno, o primeiro jogador dispara, enquanto o segundo jogador é recarregado. O jogador um vence este jogo. A mesma entrada pode, opcionalmente, ser representada como "r g f r"
, "rgfr"
, "rg fr"
"rg-fr"
...
Você pode assumir o seguinte:
A entrada corresponderá ao formato escolhido e conterá apenas caracteres válidos.
Alguém vai morrer dentro de 100 turnos.
No entanto, você não pode assumir que os turnos terminam quando alguém morre.
Resultado
Um valor que indica quem ganhou (ou quem ganhou primeiro *
). Você pode escolher o que produzir para cada cenário, mas deve levar em consideração o seguinte:
Jogador 1 vence
Jogador 2 vence
Eles se matam (empate)
Cada resultado deve ter um valor de distrito e sempre deve ser o mesmo para cada cenário.
Como exemplo: você pode exibir 1
quando o jogador 1 vence, 2
quando o jogador 2 vence e 0
em caso de empate. Você deve sempre produzir 1
quando o jogador 1 vencer, 2
quando o jogador 2 vencer e 0
em caso de empate.
Ele pode ser retornado ou impresso no stdout. O espaço em branco à direita é bom.
Só para esclarecer, o único cenário que leva a um empate é se ambos os jogadores disparam e ambos têm munição.
*
Como neste desafio, os turnos podem continuar depois que alguém morre, é possível que mais de um jogador possa vencer eventualmente. Você precisa descobrir quem ganhou primeiro, de acordo com a entrada.
Casos de teste (assumindo 1
quando P1 vence, 2
quando P2 vence e 0
empata):
"rg fr" => 1 (P1 shot P2 while they were reloading)
"rg ff" => 1 (They both shot, but only P1 had ammo)
"rr ff" => 0 (Both had ammo and shot each other)
"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)
"rr fg rf" => 2 (P2 shot P1 while they were reloading)
"rf gg rr fg rr fr" => 1
(P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.
"rr gf fr rf gg rg ff" => 1
^ Player 1 wins here. The rest to the right has no effect on the output
Isso é código de golfe, então o menor número de bytes vence!
Observe que, como mostram os casos de teste, você deve manipular movimentos "burros". É perfeitamente válido para um jogador tentar atirar quando não tem munição ou recarregar 2 turnos seguidos (e acumular apenas uma única munição).
{"rff","rgf"}
?Respostas:
Retina , 36 bytes
O formato de entrada deve ser pares separados de avanço de linha, por exemplo,
A saída é
!_
se o jogador 1 vencer,_!
se o jogador 2 vencer e!!
se houver um empate.Experimente online!(Uma suíte de testes que usa separação de espaço por conveniência.)
Eu devo ter esquecido completamente esse desafio. Tenho certeza de que eu teria tentado isso na Retina anteriormente, caso contrário. :)
Explicação
Começamos marcando fotos "válidas", transformando a primeira
f
após cadar
uma!
. Fazemos isso combinando cada umf
dos quais podemos encontrar umr
no mesmo jogador sem cruzar com o outrof
. Limitar a pesquisa ar
s no mesmo player é fácil, sempre passando três caracteres por vez.Agora descartamos todos os turnos em que alguém se guardava, porque o turno final não pode ser um deles.
Agora, mantemos apenas o primeiro turno que contém um
!
. Se um tiro válido acontecer (e sabemos que ninguém está protegido), o jogo termina.Finalmente, precisamos consolidar a string para fornecer resultados consistentes, e simplesmente fazemos isso transformando os não-
!
caracteres (umr
ouf
)_
.fonte
Python, 139 bytes
Recebe entrada no stdin na forma de uma lista de seqüências de caracteres de 2 caracteres (por exemplo, ['rf', 'rr', 'rg', 'ff']). Produz 1 se o jogador 1 vencer, -1 se o jogador 2 vencer e 0 para um empate.
Explicação: Primeiro, verifique se alguém disparou uma bala; caso contrário, o jogo termina. Depois, determinamos se os jogadores recarregaram suas armas ou gastaram sua munição.
Este é o meu primeiro post sobre codegolf :)
fonte
JavaScript (ES6),
10810793918985 bytesEconomizou 4 bytes com a ajuda de Titus
Recebe a entrada como uma matriz de seqüências de caracteres de 2 caracteres, descrevendo os movimentos executados por cada jogador.
Devoluções:
1
se o jogador 1 vencer2
se o jogador 2 vencer3
para um empateComo funciona
Mantemos uma máscara de bits
b
descrevendo quem tem um marcador carregado:Usamos a sequência De Bruijn
'ffrfgrrggf'
para identificar todas as 9 combinações possíveis de movimentos. Usamos as máscaras OR e AND para atualizar deb
acordo com a combinação de movimentação. Usamos um terceiro conjunto de máscaras de bits com ANDb
para determinar o vencedorw
. (As únicas três combinações vencedoras sendoff
,fr
erf
.)Vale a pena notar que as máscaras OR e AND podem ser armazenadas com o mesmo padrão, alternadas por duas posições.
Casos de teste
Mostrar snippet de código
fonte
0
(ninguém foi baleado) ou3
(jogadores se matam) em caso de empate. Não tenho certeza se isso é permitido. Caso contrário, eu posso retornarw%3
.&
máscara pode ser 0 parafr,rf,ff
.'312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]
ou'123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]
salve um byte; mas eles funcionam?["rr","fg","fr","rf"]
&
tem precedência mais alta que|
, portanto, alterar a ordem não deve mudar nada (além de salvar o byte). Mas a tarefa estava ausente no meu código. Tente...'123'[b='2100231'...
.Perl 6 ,
7162 bytesSolução baseada em Regex.
Recebe a entrada como uma sequência no formulário
"rg fr"
.As três saídas possíveis são os valores de enumeração
More
(jogador ganhou 1),Less
(2 jogador ganhou),Same
(desenhar) - que se transformam em essas palavras, quando impresso, ou para1
,-1
,0
quando forçado para números.Experimente online!
Como funciona
Executa duas correspondências de regex na entrada. Após a interpolação, os dois regexes são:
r[..[r|g]]*.[r|f]f
- Corresponde ao primeiro tiro bem sucedido pelo jogador 2.r[..[r|g]]*..f[r|f]
- Corresponde ao primeiro tiro bem sucedido pelo jogador 1.Em cada caso, ele retorna a posição final da correspondência (
.to
) ou infinito, se não houver correspondência.Aplica o
<=>
operador às duas posições finais da correspondência. Retorna um valor daOrder
enumeração (More
,Less
, ouSame
), dependendo se o primeiro argumento é maior, menor ou igual à segunda.fonte
some number
? E você realmente usa caracteres como esse no código Perl comum, ou é apenas para jogar golfe?[Menu] i n f
(é chamado de sequência de composição ). No entanto, todos os símbolos Perl 6 têm versões ASCII - por exemplo,Inf
e∞
são sinônimos -, portanto, não é necessário usar símbolos Unicode no código do Perl 6. I just like it ... :)Haskell ,
101 9187 bytesExperimente online! A função infix
#
usa duas strings representando as ações de cada um dos dois jogadores e retorna(0,1)
se o jogador 1 vencer,(1,0)
para o jogador 2 e(0,0)
para um empate.Exemplo de uso:
Explicação:
A função infix
!
converte uma sequência de ações'r'
(recarregar),'f'
(fogo) e'g'
(guarda) em uma sequência de ações observáveis0
(fogo real),1
(sem ação) e2
(guarda), onde uma ação de fogo é contada apenas como ação de fogo real se um marcador estiver carregado e, caso contrário , nenhuma ação será executada. Para conseguir isso, o primeiro argumenton
é0
se um marcador é carregado e1
se a arma não está carregada. Dessa forma, cada um'f'
pode simplesmente ser substituído pela correnten
. (n=0
-> carregado -> fogo real ->0
,n=1
-> descarregado -> sem ação ->1
)As nove possibilidades resultantes são então
(0,0)
: Ambos os jogadores atiram e morrem, o jogo termina.(0,1)
ou(1,0)
: Um jogador atira no outro, o jogo termina.(0,2)
ou(2,0)
: Um jogador atira, mas o outro guarda, o jogo continua.(1,1)
,(1,2)
,(2,1)
Ou(2,2)
: nenhum jogador tiros, jogo continua.Por design, a soma das opções de final de jogo é menor que 2 e a soma de cada possibilidade de continuação de jogo é maior ou igual a 2. O resultado do jogo é a primeira tupla com soma menor que 2.
fonte
Lote, 249 bytes
A entrada está na forma de pares de caracteres para cada turno e gera o nível de erro (0 = empate, 1 = jogador 1, 2 = jogador 2).
x
ey
acompanhe se o jogador tem munição; portanto, quando os dois disparam, o resultado é3-x-x-y
, a menos que seja 3; nesse caso, continuamos. Na linha 5, eu abuso o analisador de lote -%1
(que é o movimento atual) é substituído antes que ashift
instrução seja executada e removida, portanto, ainda vamos para o rótulo correto.fonte
Clojure, 168 bytes
Menos golfe (se ambas as pessoas estiverem vivas, usamos
M
para atualizar a munição e o estado de vida do inimigo, caso contrário, retornamos o status atual):Exemplo de uso (o primeiro elemento informa se o Jogador 1 está ativo no final do jogo, o segundo elemento informa se o Jogador 2 está ativo, o 3º e o 4º informam o status da munição que não é relevante na determinação do vencedor):
Atualização: Bem, olhe para isso, isso
loop
tem comprimento idêntico! Acho areduce
versão mais fácil de desenvolver, pois você pode inspecionar facilmente os estados intermediários, se usarreductions
.fonte
[l1 l2 r1 r2]
(seus valores modificados emlet
e seus valores originais) e essasfn
assinaturas.loop
. Acho que leva a um código mais puro. Assim que precisar dobrar com mais de 1 acumulador, troco.PHP,
10710190 bytesusando uma máscara de bit $ d para o status de carregamento e uma sequência DeBruijn para os movimentos de disparo.
recebe entrada como argumentos de linha de comando de 2 caracteres, executado com
-nr
.demolir
fr
:: position = 1 = P1 dispara;rf
= posição 2 = P2 dispara,ff
= posição 3 = ambos disparamg<$m
<=>f<$m[0]
(f<$m
sempre é verdade, porque existe um segundo caractere).fonte
Python, 200 bytes
fonte
turns
vez de apenast
, o que significa que o programa é muito maior que o necessário. Além disso, inicie seu envio com algo como#Python 2, 200 bytes
(supondo que este seja 2 e o programa tenha 200 bytes) para que o idioma que você está usando seja claro.Clojure,
180173 bytes-7 bytes, alterando a função para uma função completa em vez de usar uma macro. Isso permite que eu faça macros de funções internas, o que economiza um pouco.
Esta é uma solução muito literal. Estou meio confuso desde que acabei de escrever uma versão completa do jogo, e essa é basicamente uma versão bastante simplificada do algoritmo que usei. Provavelmente existem muitas otimizações que eu poderia fazer, mas estou bastante feliz com isso. Veja o código pré-escrito para explicação.
fonte