¿Puede mi equipo favorito convertirse en campeón de fútbol?

10

Como fanático de un equipo BE de fútbol como mínimo con éxito moderado , hacia el final de la temporada a menudo me pregunto si mi equipo favorito aún tiene alguna posibilidad teórica de convertirse en campeón. Su tarea en este desafío es responder esa pregunta por mí.

Entrada

Recibirá tres entradas: la tabla actual, la lista de partidos restantes y la posición actual del equipo que nos interesa.

Entrada 1: La tabla actual , una secuencia de números donde el número i son los puntos ganados por el equipo i hasta ahora. Por ejemplo, la entrada [93, 86, 78, 76, 75]codifica la siguiente tabla (solo la última columna es importante):

tabla de la liga principal


Entrada 2 : Los partidos restantes , una secuencia de tuplas donde cada tupla ( i , j ) representa un partido restante entre el equipo i y j . En el ejemplo anterior, una segunda entrada de [(1,2), (4,3), (2,3), (3,2), (1,2)]significaría que las coincidencias restantes son:

Chelsea vs Tottenham, Liverpool vs Man. City, Tottenham vs Man. City, Man. City vs Tottenham, Chelsea vs Tottenham

Entrada 3: La posición actual del equipo en el que estamos interesados. Por ejemplo, una entrada 2para el ejemplo anterior significaría que nos gustaría saber si Tottenham todavía puede convertirse en campeón.

Salida

Para cada coincidencia restante del formulario ( i , j ), hay tres resultados posibles:

  • El equipo i gana: el equipo i obtiene 3 puntos , el equipo j obtiene 0 puntos
  • El equipo j gana: el equipo i obtiene 0 puntos , el equipo j obtiene 3 puntos
  • Draw: Equipo i y j tanto obtener 1 punto

Debe generar un valor verdadero si hay algún resultado para todos los juegos restantes, de modo que al final, ningún otro equipo tenga más puntos que el equipo especificado en la tercera entrada. De lo contrario, genera un valor falso.

Ejemplo : considere la entrada ejemplar de la sección anterior:

Entrada 1 = [93, 86, 78, 76, 75], Entrada 2 = [(1,2), (4,3), (2,3), (3,2), (1,2)], Entrada 3 =2

Si el equipo 2gana todos sus partidos restantes (es decir (1,2), (2,3), (3,2), (1,2)), obtiene 4 * 3 = 12 puntos adicionales; ninguno de los otros equipos obtiene puntos de estos partidos. Digamos que el otro partido restante (es decir (4,3)) es un empate. Entonces los puntajes finales serían:

 Team 1: 93, Team 2: 86 + 12 = 98, Team 3: 78 + 1 = 79, Team 4: 76 + 1 = 77, Team 5: 75

Esto significa que ya hemos encontrado algún resultado para los partidos restantes, de modo que ningún otro equipo tiene más puntos que el equipo 2, por lo que el resultado de esta entrada debe ser verdadero.

Detalles

  • Puede suponer que la primera entrada es una secuencia ordenada, es decir, para i < j , la entrada i -ésima es igual o mayor que la entrada j -ésima. La primera entrada puede tomarse como una lista, una cadena o similar.
  • Puede tomar la segunda entrada como una cadena, una lista de tuplas o similares. Alternativamente, puede tomarlo como una matriz bidimensional adonde a[i][j]es el número de entradas del formulario (i,j)en la lista de coincidencias restantes. Por ejemplo, a[1][2] = 2, a[2][3] = 1, a[3][2] = 1, a[4][3] = 1 corresponde a [(1,2), (4,3), (2,3), (3,2), (1,2)].
  • Para la segunda y tercera entrada, puede asumir la indexación 0 en lugar de la indexación 1.
  • Puede tomar las tres entradas en cualquier orden.

Especifique el formato de entrada exacto que eligió en su respuesta.

Nodo lateral : se demostró que el problema que subyace a este desafío es NP completo en "La eliminación del fútbol es difícil de decidir bajo la regla de los 3 puntos ". Curiosamente, si solo se otorgan dos puntos por una victoria, el problema se resuelve en tiempo polinómico.

Casos de prueba

Todos los casos de prueba están en el formato Input1, Input2, Input3.

Verdad:

  • [93, 86, 78, 76, 75]` [(1,2), (4,3), (2,3), (3,2), (1,2)]`2
  • [50]` []`1
  • [10, 10, 10]` []`3
  • [15, 10, 8]` [(2,3), (1,3), (1,3), (3,1), (2,1)]`2

Falsy

  • [10, 9, 8]` []`2
  • [10, 9, 9]` [(2,3), (3,2)]`1
  • [21, 12, 11]` [(2,1), (1,2), (2,3), (1,3), (1,3), (3,1), (3,1)]`2

Ganador

Este es el , por lo que gana la respuesta correcta más corta (en bytes). El ganador será elegido una semana después de que se publique la primera respuesta correcta.

vagabundo
fuente
1
Advertencia justa. Tenemos una gran población estadounidense, por lo que agregar (fútbol) al título puede ayudar a evitar confusiones
Christopher
@Christopher es fútbol. Los estadounidenses se equivocan
caird coinheringaahing
¡También ve Chelsea!
caird coinheringaahing
@cairdcoinheringaahing Los estadounidenses están equivocados NEVR. Pero mi punto sigue en pie
Christopher
1
Nadie recuerda a australianos y canadienses.
Robert Fraser

Respuestas:

4

Haskell (Lambdabot) , 84 bytes

Gracias a @bartavelle por salvarme un byte.

Sin Lambdabot, agregue 20 bytes para import Control.Lensmás una nueva línea.

La función toma sus argumentos en el mismo orden que se describe en el OP, indexado a 0. Su segundo argumento (la lista de emparejamientos restantes) es una lista plana de índices (por ejemplo, [1,2,4,1]corresponde a [(Team 1 vs Team 2), (Team 4 vs Team 1)]).

Las reglas son un poco vagas en cuanto a si esto está permitido o no. Si no está permitido, la función puede recibir información en el formato proporcionado por los ejemplos: una lista de tuplas. En ese caso, agregue 2 bytes a la puntuación de esta solución, debido al reemplazo a:b:rcon (a,b):r.

(!)=(+~).element
(t?(a:b:r))s=any(t?r)[a!3$s,b!3$s,b!1$a!1$s]
(t?_)s=s!!t==maximum s

Explicación:

La primera línea define una función infija !de tres variables, de tipo (!) :: Int -> Int -> [Int] -> [Int], que incrementa el valor en un índice dado en una lista. Dado que, a menudo, el código es más fácil de entender que las palabras (y dado que la sintaxis de Haskell puede ser extraña), aquí hay una traducción de Python:

def add(index, amount, items):
    items[index] += amount
    return items

La segunda línea define otra función infija ?, también de tres variables (la entrada de desafío). Lo reescribiré de manera más legible aquí:

(t ? a:b:r) s = any (t ? r) [a ! 3 $ s, b ! 3 $ s, (b ! 1 $ a) ! 1 $ s]
(t ? _) s = (s !! t) == maximum s

Esta es una implementación recursiva de búsqueda exhaustiva. Se repite sobre la lista de juegos restantes, ramificando en los tres resultados posibles, y luego, una vez que la lista está vacía, verifica si nuestro equipo tiene o no la cantidad máxima de puntos. De nuevo en Python (no idiomático), esto es:

def can_still_win(standings, games_left, our_team):
    if games_left == []:
        return standings[our_team] == max(standings)
    team1, team2, other_games = games_left[0], games_left[1], games_left[2:]
    team1Wins, team2Wins, tie = standings.copy(), standings.copy(), standings.copy()
    team1Wins[team1] += 3
    team2Wins[team2] += 3
    tie[team1] += 1
    tie[team2] += 1
    return (can_still_win(team1Wins, other_games, our_team)
            or can_still_win(team2Wins, other_games, our_team)
            or can_still_win(tie, other_games, our_team))

Pruébalo en línea!

* Lamentablemente, TiO no es compatible con Lens, por lo que este enlace no se ejecutará realmente.

Tutleman
fuente
La lista plana de índices está permitida como formato de entrada :)
vauge
Parece que puede guardar un byte al no usar los guardias: ¡ Pruébelo en línea!
bartavelle
@bartavelle ¡Buena llamada! ¡Gracias! Me las arreglé para cortar otro byte intercambiando el orden de las definiciones de funciones por lo que podría reemplazar []con _.
Tutleman
3

Microsoft SQL Server, 792 bytes

CREATE FUNCTION my.f(@s XML,@m XML,@ INT)RETURNS TABLE RETURN
WITH s AS(SELECT s.value('@p','INT')p FROM @s.nodes('S')s(s)),
m AS(SELECT m.value('@i','INT')i,m.value('@j','INT')j FROM @m.nodes('M')m(m)),
a AS(SELECT ROW_NUMBER()OVER(ORDER BY-p)t,p FROM s),
b AS(SELECT p+3*(SELECT COUNT(*)FROM m WHERE t IN(i,j))o FROM a WHERE t=@),
c AS(SELECT i,j,ROW_NUMBER()OVER(ORDER BY 1/0)k FROM m WHERE @ NOT IN(i,j)),
d AS(SELECT COUNT(*)u,POWER(3,COUNT(*))-1 v FROM c UNION ALL SELECT u,v-1 FROM d WHERE v>0),
e AS(SELECT v,u,v/3 q,v%3 r FROM d UNION ALL SELECT v,u-1,q/3,q%3 FROM e WHERE u>1),
f AS(SELECT v,p+SUM(IIF(t=i,r,(2-r))%3*3/2)s FROM a,c,e WHERE t IN(i,j)AND k=u GROUP BY v,t,p),
g AS(SELECT MAX(s)x FROM f GROUP BY v)SELECT SUM(IIF(o<ISNULL(x,p),0,1))f FROM a,(b OUTER APPLY g)WHERE t=1;

La función devuelve 0 para un resultado falso y más de 0 para uno verdadero.

Todo el fragmento:

SET NOCOUNT ON;
--USE tempdb;
USE rextester;
GO
IF SCHEMA_ID('my') IS NULL EXEC('CREATE SCHEMA my');
ELSE BEGIN
  IF OBJECT_ID('my.f', 'IF') IS NOT NULL DROP FUNCTION my.f;
  IF OBJECT_ID('my.s', 'U') IS NOT NULL DROP TABLE my.s;
  IF OBJECT_ID('my.m', 'U') IS NOT NULL DROP TABLE my.m;
  IF OBJECT_ID('my.c', 'U') IS NOT NULL DROP TABLE my.c;
END;
GO
CREATE TABLE my.c( -- Test cases
  c INT PRIMARY KEY CLUSTERED CHECK(c > 0), -- Test Case Id
  n INT CHECK(n > 0), -- Current position of the team of interest
);
CREATE TABLE my.s( -- Standings
  a INT FOREIGN KEY REFERENCES my.c(c) CHECK(a > 0), -- Test cAse Id
  p INT CHECK(p > 0) -- Team pts
);
CREATE TABLE my.m( -- Matches
  s INT FOREIGN KEY REFERENCES my.c(c) CHECK(s > 0), -- Test caSe Id
  i INT CHECK(i > 0), -- Team i
  j INT CHECK(j > 0), -- Team j
  CHECK(i != j)
);
GO
INSERT my.c(c, n) VALUES (1, 2), (2, 1), (3, 3), (4, 2), (5, 2), (6, 1), (7, 2);
INSERT my.s(a, p) VALUES (1, 93), (1, 86), (1, 78), (1, 76), (1, 75),
(2, 50), (3, 10), (3, 10), (3, 10), (4, 15), (4, 10), (4, 8),
(5, 10), (5, 9), (5, 8), (6, 10), (6, 9), (6, 9), (7, 21), (7, 12), (7, 11);
INSERT my.m(s, i, j) VALUES (1, 1, 2), (1, 4, 3), (1, 2, 3), (1, 3, 2), (1, 1, 2),
(4, 2, 3), (4, 1, 3), (4, 1, 3),(4, 3, 1), (4, 2, 1), (6, 2, 3), (6, 3, 2),
(7, 2, 1), (7, 1, 2), (7, 2, 3), (7, 1, 3), (7, 1, 3), (7, 3, 1), (7, 3, 1);
GO
CREATE FUNCTION my.f(@s XML,@m XML,@ INT)RETURNS TABLE RETURN
WITH s AS(SELECT s.value('@p','INT')p FROM @s.nodes('S')s(s)),
m AS(SELECT m.value('@i','INT')i,m.value('@j','INT')j FROM @m.nodes('M')m(m)),
a AS(SELECT ROW_NUMBER()OVER(ORDER BY-p)t,p FROM s),
b AS(SELECT p+3*(SELECT COUNT(*)FROM m WHERE t IN(i,j))o FROM a WHERE t=@),
c AS(SELECT i,j,ROW_NUMBER()OVER(ORDER BY 1/0)k FROM m WHERE @ NOT IN(i,j)),
d AS(SELECT COUNT(*)u,POWER(3,COUNT(*))-1 v FROM c UNION ALL SELECT u,v-1 FROM d WHERE v>0),
e AS(SELECT v,u,v/3 q,v%3 r FROM d UNION ALL SELECT v,u-1,q/3,q%3 FROM e WHERE u>1),
f AS(SELECT v,p+SUM(IIF(t=i,r,(2-r))%3*3/2)s FROM a,c,e WHERE t IN(i,j)AND k=u GROUP BY v,t,p),
g AS(SELECT MAX(s)x FROM f GROUP BY v)SELECT SUM(IIF(o<ISNULL(x,p),0,1))f FROM a,(b OUTER APPLY g)WHERE t=1;
GO
SELECT c, f
FROM my.c
OUTER APPLY(SELECT p FROM my.s S WHERE a = c FOR XML AUTO)S(s)
OUTER APPLY(SELECT i, j FROM my.m M WHERE s = c FOR XML AUTO)M(m)
OUTER APPLY my.f(s, m, n)
ORDER BY c
OPTION(MAXRECURSION 0);

¡Compruébalo en línea!

Andrei Odegov
fuente
De todos los idiomas por qué esto xD
Noah Cristino
Por una diversidad :)
Andrei Odegov
Eso debe haber sido divertido de programar :)
Noah Cristino
1

Python 2, 242 221 bytes

from itertools import*
def u(S,M,t,O):
 for m,o in zip(M,O):
  if t in m:S[t]+=3
  else:S[m[0]]+=(1,3,0)[o];S[m[1]]+=(1,0,3)[o]
 return S[t]>=max(S)
f=lambda s,m,t:any(u(s[:],m,t,O)for O in product([0,1,2],repeat=len(m)))

Pruébalo en línea!

Después de un primer pase con pensamiento básico de golf. Toma entrada con indexación basada en 0 ; los casos de prueba en TIO se ajustan a esto a través de la función F.

La product([0,1,2],repeat=len(m))iteración evalúa los posibles resultados sobre empate / victoria / pérdida para cada partido a menos que el equipo de interés (TOI) sea parte del partido (en el que siempre se supone que el TOI gana).

Chas Brown
fuente
1

JavaScript (ES6), 145 bytes

(s,d,t,o=[],g=(c=s,i=0)=>d[i]?[3,,0,3,1,1].map((a,j)=>(j%=2,r=j?r:[...c],r[d[i][j]]+=a,g(r,i+1))):o.push(c))=>o.some(r=>r[t]==Math.max(...r),g())

Toma la entrada de puntaje como una matriz ( [93,86,78,76,75]), los próximos juegos como una matriz de matrices de 2 valores ( [[0,1],[3,2],[1,2],[2,1],[0,1]]) y el índice del equipo como un entero ( 1). Todo está indexado a 0.

Fragmento de prueba

Justin Mariner
fuente