Antecedentes
Me inspiró el reciente video de 3Blue1Brown sobre el problema de división del collar (o como él lo llama, el problema del collar robado) y su relación con el teorema de Borsuk-Ulam .
En este problema, dos ladrones han robado un collar valioso que consta de varios tipos diferentes de joyas. Hay un número par de cada tipo de joya y los ladrones desean dividir cada tipo de joya de manera uniforme entre los dos. El problema es que deben hacerlo dividiendo el collar en un número de segmentos contiguos y distribuir los segmentos entre los dos.
Aquí hay un ejemplo con cuatro tipos de joya denotados S
, E
, D
, y R
(por zafiro, esmeralda, diamante y rubí, respectivamente). Digamos que el collar es el siguiente:
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
Hay 8
zafiros, 10
esmeraldas, 4
diamantes y 6
rubíes. Podemos dividir el collar de la siguiente manera:
[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
Luego, si le damos los segmentos primero, tercero y quinto a un ladrón y el segundo y cuarto segmentos al otro ladrón, cada uno terminará con 4
zafiros, 5
esmeraldas, 2
diamantes y 3
rubíes:
[S], [S,E,S,D,E,R,S], [R,R,D,E,E,E]
[S], [R,E,S,S,S,D,R,E,E,R,E,D,E],
Usando 0
-indexing, estos cortes ocurren en los índices [1,2,9,22]
.
Objetivo
Resulta que una división tan justa siempre se puede hacer con la mayoría de los n
cortes, donde n
está el número de tipos de joyas. Su tarea es escribir un programa o función completa que tome un collar como entrada y produzca una división mínima (número mínimo de cortes).
Entrada
La entrada puede estar en cualquier formato conveniente. El collar debe ser una secuencia de joyas y nada más; Por ejemplo, una lista de enteros, diccionario con claves que representan los tipos de joyas y los valores que son listas de índices. Opcionalmente, puede incluir la longitud del collar o el número de tipos distintos de joyas, pero no debe tomar ninguna otra entrada.
Puede suponer que el collar de entrada es válido. No es necesario manejar el caso donde hay un número impar de joyas de un tipo dado o el collar está vacío.
Salida
Nuevamente, la salida puede estar en cualquier formato conveniente; por ejemplo, una lista de segmentos, una lista de posiciones de corte, un diccionario con claves que representan a los dos ladrones y los valores como listas de segmentos, etc. Los segmentos pueden representarse por su índice inicial, índice final, lista de índices consecutivos, lista de joyas, sus longitudes, etc. Puede usar 0
- o 1
- indexación. Si el orden no es significativo para su formato, entonces su salida puede estar en cualquier orden. Aquí está la salida anterior en varios formatos diferentes:
list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
list of cuts: [1,2,9,22]
list of lengths: [1,1,7,13,6]
dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]}
Tenga en cuenta que el orden es importante en la lista de segmentos (los segmentos se alternan entre los ladrones) y la lista de longitudes (para identificar los segmentos), pero no en la lista de cortes o el diccionario. Editar: Greg Martin señaló que estos no serían resultados válidos ya que se puede obtener una división justa en dos cortes
Casos de prueba
[1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]]
[1,1,1,1,2,2,3,3,3,3,3,3] -> [[1,1],[1,1,2],[2,3,3,3],[3,3,3]]
[1,1,1,1,1,1,1,1,1,1,1,1] -> [[1,1,1,1,1,1],[1,1,1,1,1,1]]
[1,1,1,1,2,3,4,2,3,4,2,2] -> [[1,1],[1,1,2,3,4,2],[3,4,2,2]]
Notas
- Las lagunas estándar están prohibidas.
- Este es el código de golf ; la respuesta más corta (en bytes) gana.
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
, parece que la salida debería ser [[S,S,S,E,S,D,E,R],[S,R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
, ya que tiene menos cortes que [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
. ¿Estoy entendiendo la especificación correctamente?