¿Es un prefijo válido de penaltis?

14

En el fútbol de asociación (también conocido como fútbol), un lanzamiento de penalti es la segunda medida de desempate que se puede usar en un partido que no puede terminar en un empate, después de un tiempo extra (es decir, tiempo extra de fútbol de asociación).

En una tanda de penaltis, el árbitro principal arroja una moneda para determinar en qué objetivo ocurre la tanda de tiros, y luego lanza otra moneda para determinar qué equipo comienza primero. Sin embargo, lo único relevante para este desafío es lo que sucede entonces, que se describe a continuación.

Cada equipo tiene 5 penalizaciones disponibles al inicio, y el puntaje de penalización es 0-0. Si, en algún momento, las penalizaciones restantes de un equipo no son suficientes para cambiar el equipo ganador actual, el tiroteo se detiene.

Si no quedan penalizaciones restantes, pero los puntos de ambos equipos son iguales, se otorga una penalización adicional a ambos equipos. Esto se repite hasta que los puntos no sean iguales.

Después de que el tiroteo se detiene, el equipo con el mayor puntaje de penalización gana el juego.

Desafío

Su desafío es, dadas dos listas Ay Brepresentando qué penalizaciones anotaron el equipo A y el equipo B, respectivamente, para determinar si representan un penal penal válido. Un tiroteo es válido si se puede alcanzar el estado representado por la entrada, independientemente de si se puede determinar el equipo ganador. Tenga en cuenta que posiblemente tenga que probar ambos escenarios (inicio del Equipo A, inicio del Equipo B), ya que, si el estado descrito en la entrada es accesible para al menos un escenario, la entrada es válida. Si las longitudes de las listas son diferentes, el equipo representado por el más largo comienza primero (solo puede tener un elemento más que el otro, y el equipo de la lista más corta no puede comenzar, ya que el equipo de la lista más larga lanzaría dos penalizaciones) en una fila, ya que la lista más corta se agotará prematuramente).

Ejemplos detallados

Puede saltar a la sección de Reglas a continuación, estas son solo para ayudar a resolver el desafío.

Suponga que obtiene este tiroteo como entrada, donde -significa que no se marcó ningún gol y Xsignifica que se marcó un gol (no es vá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.

Por el contrario, aquí hay un ejemplo 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.

Otro ejemplo, esta vez con penalizaciones adicionales:

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.

Aquí hay una entrada válida donde es demasiado pronto para determinar el ganador:

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, aquí hay una entrada donde las longitudes de las listas difieren:

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.

Reglas

  • El equipo que dispara primero puede ser A o B, no puedes asumir que uno siempre disparará primero.
  • Las listas tendrán la misma longitud o sus longitudes diferirán en una.
  • Puede elegir dos valores distintos y consistentes para representar penalizaciones puntuadas / no puntuadas.
  • Las listas también se pueden representar como enteros convertidos a partir de la base 2 del bijective , cadenas o el formato de lista nativo de su idioma. Si se elige un formato biyectiva base 2, se aplican las reglas de entrada a los números convertidos a la base biyectiva 2 (de modo dígitos 1y 2bien puede significar anotada y no precortada o no precortada y obtuvo respectivamente). El binario regular no está permitido , ya que no se puede determinar la presencia de ceros a la izquierda en la representación binaria prevista.
  • Este es el , por lo que gana la solución más corta. Sin embargo, no se desanime de responder incluso si parece que su idioma no puede "vencer a los especializados".

Casos de prueba

En estos casos de prueba, un 0representará un no objetivo y un 1representará un objetivo.

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]
Erik el Outgolfer
fuente
¿Puedo devolver 0 o falso para inválido y devolver verdadero para válido?
Encarnación de la ignorancia
@EmbodimentofIgnorance "Puede elegir dos valores distintos y consistentes para representar penalizaciones puntuadas / no puntuadas". Los valores exactos no importan, pero solo debe haber dos valores.
Erik the Outgolfer
Supongo [[0,0],[1,1]](o cualquier caso de prueba en el que una de las dos listas internas tiene 2 elementos) es verdad, ya que el juego todavía está en curso (al igual que los casos de prueba con [[0],[1]]o [[0],[]]aún están en progreso).
Kevin Cruijssen
@KevinCruijssen Sí, porque nadie puede determinar quién ganará, el resultado podría ser 3-2. ;-)
Erik the Outgolfer

Respuestas:

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)

Pruébalo en línea!

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
Arnauld
fuente
2

Python 2 , 176 169 171 169 bytes

-2 bytes gracias 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)

Pruébalo en línea! (Incluyendo algunos casos de prueba adicionales no mencionados anteriormente).

Crea una función fque toma dos argumentos (las dos listas de penalizaciones con puntaje / sin puntaje) y devuelve Truesi los puntajes son posiblemente válidos o Falseno.

Explicación parcial:

En primer lugar, la execconstrucción es solo una forma de ahorrar unos pocos bytes al no tener que repetir la expresión len(a+b)más de una vez. El código anterior es equivalente a lo siguiente:

Actualización: la respuesta nueva y mejorada es el mismo número de bytes con o sin exectrucos, por lo que, en aras de la simplicidad, lo he eliminado.

Actualización 2: la nueva versión corregida incluye incluso más compresión de cadenas mediante sustitución y exec. Sí, uso el %formato y a .replaceen la misma cadena. El código anterior es 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)

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

Sin embargo, para ser un conjunto válido de puntajes, una entrada no necesita ser estrictamente continuable, sino que debe haber sido continuable antes de que se haya realizado la última patada. Esta condición es equivalente a decir que debe 1) haber sido continuable la última vez que ambas partes habían pateado la misma cantidad de veces y 2) estar dentro de dos puntos y medio de ser continuable, que es donde hentra el argumento final : h(a[:~-len(a+b)/2],b[:~-len(a+b)/2],6)prueba la condición 1) y h(a,b,7)( 7representa los dos medios puntos adicionales permitidos en el margen) prueba la condición 2).

El caso en el que cada equipo ha pateado un máximo de cinco veces se ha resuelto. (La explicación continuará para el otro caso).

En términos de golf de bajo nivel, dudo que haya demasiado para afeitarse, pero algorítmicamente probablemente podría hacerse un poco más simple.

Aidan F. Pierce
fuente
1
Puede jugar al golf (%s-1)/2a ~-%s/2salvar 2 bytes.
Kevin Cruijssen
@KevinCruijssen ¡Gracias!
Aidan F. Pierce
1

Gelatina , 62 54 49 bytes

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

Pruébalo en línea!

ṫ⁵Ṗ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Ç

Tenga en cuenta que el código de pie de página en tio es solo para manejar múltiples casos de prueba e imprimir salidas contra entradas.

Gracias a @EriktheOutgolfer por jugar golf en 8 bytes

Nick Kennedy
fuente
¡Buen intento! Este no es un desafío muy trivial. Algunos campos de golf.
Erik the Outgolfer
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}

Pruébalo en línea!

Devuelve falsey para tiroteos válidos, verdad para los inválidos.

Explicación

# 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
nwellnhof
fuente