É um prefixo válido de pênaltis?


14

No futebol de associação (também conhecido como futebol), uma disputa de pênaltis é a segunda medida de desempate que pode ser usada em uma partida que não pode terminar em um empate, após o prolongamento (por exemplo, horas extras na associação de futebol).

Em uma disputa de pênaltis, o árbitro principal joga uma moeda para determinar em qual gol o tiroteio acontece e, em seguida, joga outra moeda para determinar qual time começa primeiro. No entanto, a única coisa relevante para esse desafio é o que acontece então, descrito abaixo.

Cada equipe tem 5 pênaltis disponíveis no início e o placar da penalidade é 0-0. Se, a qualquer momento, as penalidades remanescentes de uma equipe não forem suficientes para alterar a equipe vencedora, o tiroteio será interrompido.

Se não houver penalidades restantes, mas os pontos de ambas as equipes forem iguais, uma penalidade adicional será concedida a ambas as equipes. Isso é repetido até que os pontos não sejam iguais.

Após o desempate, a equipe com a maior pontuação de penalidade vence o jogo.

Desafio

Seu desafio é, dadas duas listas Ae Brepresentando quais penalidades o time A e o time B marcaram respectivamente, para determinar se eles representam um pênalti válido. Um desempate é válido se o estado representado pela entrada puder ser alcançado, independentemente de a equipe vencedora poder ser determinada. Observe que é possível testar os dois cenários (início do Time A, início do Time B), pois, se o estado descrito na entrada estiver acessível para pelo menos um cenário, a entrada será válida. Se os comprimentos das listas forem diferentes, a equipe representada pela mais longa começa primeiro (só pode ter mais um elemento que o outro e a equipe da lista mais curta não pode começar, pois a equipe da lista mais longa aplicaria duas penalidades seguidas, pois a lista mais curta será esgotada prematuramente).

Exemplos detalhados

Você pode pular para a seção Regras abaixo, apenas para ajudar a solucionar o desafio.

Suponha que você receba essa disputa como entrada, onde -significa que nenhum gol foi marcado e Xsignifica que um gol foi marcado (é inválido):

Team A: - X X X X
Team B: - - - - X

Assuming team A starts first:

Team A: - (0 - 0) (max possible score 4 - 5)
Team B: - (0 - 0) (max possible score 4 - 4)
Team A: X (1 - 0) (max possible score 4 - 4)
Team B: - (1 - 0) (max possible score 4 - 3)
Team A: X (2 - 0) (max possible score 4 - 3)
Team B: - (2 - 0) (max possible score 4 - 2)
Team A: X (3 - 0) (max possible score 4 - 2)
Team A already has a higher score than B could ever have, but the input hasn't
ended yet, so it's invalid if team A is first.

Assuming team B starts first:

Team B: - (0 - 0) (max possible score 5 - 4)
Team A: - (0 - 0) (max possible score 4 - 4)
Team B: - (0 - 0) (max possible score 4 - 3)
Team A: X (1 - 0) (max possible score 4 - 3)
Team B: - (1 - 0) (max possible score 4 - 2)
Team A: X (2 - 0) (max possible score 4 - 2)
Team B: - (2 - 0) (max possible score 4 - 1)
Team A already has a higher score than B could ever have, but the input hasn't
ended yet, so it's invalid if team B stars first.

The input is invalid no matter which team starts first, so it's considered
invalid.

Pelo contrário, aqui está um exemplo válido:

Team A: X X X
Team B: - - -

Assuming team A starts first:

Team A: X (1 - 0) (max possible score 5 - 5)
Team B: - (1 - 0) (max possible score 5 - 4)
Team A: X (2 - 0) (max possible score 5 - 4)
Team B: - (2 - 0) (max possible score 5 - 3)
Team A: X (3 - 0) (max possible score 5 - 3)
Team B: - (3 - 0) (max possible score 5 - 2)
It can be determined that team A wins, however the input has ended, so it's
valid if team A starts first. Therefore, the input is valid.

Outro exemplo, desta vez com multas extras:

Team A: X - X - - - X -
Team B: - X X - - - X X

Assuming team A starts first:

Team A: X (1 - 0) (max possible score 5 - 5)
Team B: - (1 - 0) (max possible score 5 - 4)
Team A: - (1 - 0) (max possible score 4 - 4)
Team B: X (1 - 1) (max possible score 4 - 4)
Team A: X (2 - 1) (max possible score 4 - 4)
Team B: X (2 - 2) (max possible score 4 - 4)
Team A: - (2 - 2) (max possible score 3 - 4)
Team B: - (2 - 2) (max possible score 3 - 3)
Team A: - (2 - 2) (max possible score 2 - 3)
Team B: - (2 - 2) (max possible score 2 - 2)
First 5 penalties result in a tie, so we move on to extra penalties.
Team A: -, Team B: - (2 - 2)
Team A: X, Team B: X (3 - 3)
Team A: -, Team B: X (3 - 4)
It can be determined that team B wins, however the input has ended, so it's
valid if team A starts first. Therefore, the input is valid.

Aqui está uma entrada válida em que é muito cedo para determinar o vencedor:

Team A: X X - -
Team B: - X - X

Assuming team A starts first:

Team A: X (1 - 0) (max possible score 5 - 5)
Team B: - (1 - 0) (max possible score 5 - 4)
Team A: X (2 - 0) (max possible score 5 - 4)
Team B: X (2 - 1) (max possible score 5 - 4)
Team A: - (2 - 1) (max possible score 4 - 4)
Team B: - (2 - 1) (max possible score 4 - 3)
Team A: - (2 - 1) (max possible score 3 - 3)
Team B: X (2 - 2) (max possible score 3 - 3)
The input has ended before the winner can be determined, so it's valid if team A
starts first. Therefore, the input is valid.

Finalmente, aqui está uma entrada em que os comprimentos das listas diferem:

Team A: - - -
Team B: X X - X

Since team B shot more penalties, it starts first:

Team B: X (0 - 1) (max possible score 5 - 5)
Team A: - (0 - 1) (max possible score 4 - 5)
Team B: X (0 - 2) (max possible score 4 - 5)
Team A: - (0 - 2) (max possible score 3 - 5)
Team B: - (0 - 2) (max possible score 3 - 4)
Team A: - (0 - 2) (max possible score 2 - 4)
Team B: X (0 - 3) (max possible score 2 - 4)
It can be determined that team B wins, however the input has ended, so it's
valid.

Regras

  • O time que atira primeiro pode ser A ou B, não se pode presumir que um sempre atire primeiro.
  • As listas terão o mesmo comprimento ou diferirão em um.
  • Você pode escolher dois valores distintos e consistentes para representar penalidades marcadas / não marcadas.
  • As listas também podem ser representadas como números inteiros convertidos da base bijetiva 2, strings ou formato de lista nativa do seu idioma. Se um formato bijetivo de base 2 for escolhido, as regras de entrada se aplicarão aos números convertidos em bijective base 2 (portanto, dígitos 1e 2podem significar pontuação e sem pontuação ou sem pontuação e pontuação respectivamente). Binário regular não é permitido , pois não é possível determinar a presença de zeros à esquerda na representação binária pretendida.
  • Isso é , então a solução mais curta vence. No entanto, não desanime de responder, mesmo que pareça que seu idioma não possa "superar os especializados".

Casos de teste

Nesses casos de teste, a 0representará uma meta sem objetivo e a 1representará uma meta.

Formato:

[Team A], [Team B]

Entradas válidas:

[], []
[0], [0]
[0], [1]
[1], [1]
[0], []
[1, 1, 1, 1], [0, 0, 1, 1]
[0, 1, 1, 1, 1], [0, 1, 1, 0]
[0, 0, 0, 0, 1], [0, 0, 0, 1, 0]
[0, 0, 0, 0, 1], [0, 0, 0, 1]
[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]
[0, 1, 1, 1, 1], [0, 1, 1, 0, 1]
[1, 1, 1], [0, 0, 0]
[1, 1, 1, 1], [0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Entradas inválidas:

[0, 1, 1, 1, 1], [0, 1, 1, 0, 0]
[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1]
[1, 1, 1, 0], [0, 0, 0]
[1, 1, 1, 1], [0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1]
[0, 0, 0, 0, 1], [0, 1, 1, 1, 0]

Posso retornar 0 ou falso para inválido e retornar verdadeiro para válido?
Modalidade de ignorância

@EmbodimentofIgnorance "Você pode escolher dois valores distintos e consistentes para representar penalidades marcadas / não marcadas". Os valores exatos não importam, mas deve haver apenas dois valores.
Erik the Outgolfer 06/03/19

Presumo que [[0,0],[1,1]](ou qualquer caso de teste em que uma das duas listas internas tenha 2 itens) seja verdade, pois o jogo ainda está em andamento (assim como os casos de teste com [[0],[1]]ou [[0],[]]ainda estão em andamento)?
Kevin Cruijssen 7/03/19

@KevinCruijssen Sim, porque ninguém pode determinar quem vencerá, o resultado pode ser 3-2. ;-)
Erik the Outgolfer 07/03/19

Respostas:


3

JavaScript (ES6),  117 112  109 bytes

(a)(b)120 01

a=>b=>!(g=(a,b,P=Q=i=5)=>(p=a[5-i])|(q=b[5-i])&&(--i<0?P-Q:P-Q>i|Q+q-P-p>i&p<2)|g(a,b,P+p,Q+=q))(a,b)|!g(b,a)

Experimente online!

Comentado

a => b =>                   // given a[] and b[]
  !(g = (                   // g is a recursive function taking:
      a,                    //   the results a[] of the team that plays first
      b,                    //   the results b[] of the team that plays second
      P =                   //   the cumulated goals P of the 1st team (relative value)
      Q =                   //   the cumulated goals Q of the 2nd team (relative value)
      i = 5                 //   a counter i
    ) =>                    // and returning a truthy value if something goes wrong
      (p = a[5 - i]) |      // if either the first team
      (q = b[5 - i]) && (   // or the second team is playing this round:
        --i < 0 ?           //   decrement i; if we've played more than 5 penalties:
          P - Q             //     do we already have a goal difference?
        :                   //   else:
          P - Q > i |       //     was the 1st team already guaranteed to win?
          Q + q - P - p > i //     or is the 2nd team now guaranteed to win
          & p < 2           //     while the 1st team failed its last attempt?
      ) |                   //
      g(                    //   do a recursive call:
        a, b,               //     pass a[] and b[] unchanged
        P + p,              //     update P
        Q += q              //     update Q
      )                     //   end of recursive call
  )(a, b) |                 // try g(a, b)
  !g(b, a)                  // try g(b, a); return 1 if at least one of them is falsy

2

Python 2 , 176 169 171 169 bytes

-2 bytes graças a @Kevin Cruijssen

exec"h=lambda a,b,m:m-%s/2>abs(sum(a)-sum(b));f=lambda a,b:a[5#==b[5#and h(a[:5],b[:5],6)if %s>10else h(a,b,7)and h(a[#,b[#,6)".replace("#",":~-%s/2]")%(("len(a+b)",)*6)

Experimente online! (Incluindo alguns casos de teste extras não listados acima.)

Cria uma função fque recebe dois argumentos (as duas listas de penalidades pontuadas / não pontuadas) e retorna Truese as pontuações são possivelmente válidas ou Falsenão.

Explicação parcial:

Primeiro, a execconstrução é apenas uma maneira de salvar alguns bytes, não sendo necessário repetir a expressão len(a+b)mais de uma vez. O trecho de código acima é equivalente ao seguinte:

Atualização: a resposta nova e aprimorada é a mesma contagem de bytes com ou sem exectruques, portanto, por uma questão de simplicidade, eu a removi.

Atualização 2: A nova versão corrigida por bug inclui ainda mais compactação de strings via substituição e exec. Sim, eu uso %formatação e a .replacena mesma string. O código acima é equivalente a:

h=lambda a,b,m:m-len(a+b)/2>abs(sum(a)-sum(b))
f=lambda a,b:a[5:(len(a+b)-1)/2]==b[5:~-len(a+b)/2]and h(a[:5],b[:5],6)if len(a+b)>10else h(a,b,7)and h(a[:(~-len(a+b)/2],b[:(len(a+b)-1)/2],6)

<=5not len(a+b)>10hm

No entanto, para ser um conjunto válido de pontuações, uma entrada não precisa ser estritamente continuável, mas deve ter sido continuável antes do último chute a ser feito. Essa condição equivale a dizer que deve 1) ter sido continuável na última vez em que os dois lados chutaram o mesmo número de vezes e 2) estar atualmente dentro de dois meios pontos de continuidade - e é aí que hentra o argumento final : h(a[:~-len(a+b)/2],b[:~-len(a+b)/2],6)testa a condição 1) e h(a,b,7)(o que 7representa dois pontos extras permitidos na margem) testa a condição 2).

O caso em que cada equipe chutou no máximo cinco vezes foi resolvido. (Explicação a ser continuada no outro caso.)

Em termos de golfe de baixo nível, duvido que exista muita coisa para se barbear, mas algoritmicamente isso provavelmente poderia ser feito de maneira um pouco mais simples.


1
Você pode golfe (%s-1)/2para ~-%s/2salvar 2 bytes.
Kevin Cruijssen 7/03/19

@KevinCruijssen Thanks!
Aidan F. Pierce

1

Geléia , 62 54 49 bytes

ṫ⁵Ṗm2¬Ạ
N§ỤḢƊ¦LÞṚZFĵ12R:2U_ṁḣ⁵ṫ-N<Ø.ẠaÇoL<3
ṚÇoÇ

Experimente online!

ṫ⁵Ṗm2¬Ạ # helper function to determine whether
        # even indices at or beyond 10 are zero
ṫ⁵      # tail - take every item from 10
  Ṗ     # remove last item
   m2   # take every second item
     ¬  # logical not, will return 1 for an empty list
      Ạ # all
# function to create cumulative score
# difference and check values
N§ỤḢƊ¦    # negate scores for team with lower score
          # (or one of them if both same score)
  LÞṚ     # sort by length, longest first
  ZF      # transpose lists and flatten
  Ä       # cumulative sum
  µ       # this cumulative score difference (CSD) 
          # now becomes left value
  12R:2U_ # subtract cumulative score difference from
          # 6,5,5,4,4,3,3,2,2,1
  ṁḣ⁵     # shorten to be no longer than 10 items
          # and no longer than CSD
  ṫ-N<Ø.Ạ # check last two values are greater than 0,-1
  aÇ      # check that helper function also TRUE
  oL<3    # handle very short scores
# main link that calls the above for scores in either order
ṚÇoÇ

Observe que o código do rodapé é apenas para lidar com vários casos de teste e imprimir saídas nas entradas.

Graças a @EriktheOutgolfer por jogar fora 8 bytes


Boa tentativa! Este não é um desafio muito trivial. Alguns golfe.
Erik the Outgolfer 07/03/19

0

Perl 6 , 123 bytes

{all map {@^b>@^a||[R,](map {abs(($+=$_)-++$ %2/2)>(5-++$ /2 max++$ %2)},flat roundrobin @a,-<<@b).skip.any},@^a,@^b,@b,@a}

Experimente online!

Retorna falsey para tiroteios válidos, mas para os inválidos.

Explicação

# Check whether block returns true (invalid shoot-out) for arguments (a, b) and (b, a)
{all map {...},@^a,@^b,@b,@a}
# Return true (invalid) if array b is longer than a
@^b>@^a||
# Return true (invalid) if any except the last value is true (shoot-out stopped)
[R,](...).skip.any
# Map values from a and negated b, interleaved
map {...},flat roundrobin @a,-<<@b
# Shoot out stopped?
abs(($+=$_)-++$ %2/2)>(5-++$ /2 max++$ %2)
    #     # Accumulator
           #        # Subtract 0.5 for first team
                      #                  # Sequence 4.5 4 3.5 3 2.5 2 1.5 1 1 0 1 0 1 0
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.