Codifica cada elemento del conjunto con un número primo.
Ex:
a -> 2
b -> 3
c -> 5
etc.
Ahora, se necesitan dos listas más que mantener.
La primera lista es para primos, la segunda es para sus exponentes.
La idea es; cuando tropiezas con un elemento, registra su número primo y cuántas veces en sucesión aparece.
Para [a, b, b, c]
, se obtiene lo siguiente:
[2, 3, 3, 5]
que puede ser registrado como:
[2, 3^2, 5]
o, más precisamente:
[2^1, 3^2, 5^1]
y mantener dos listas:
[2,3,5] // primes in succession - list [p]
[1,2,1] // exponents - list [e]
Ahora, itere a través de estas dos listas de extremos a medios, verificando si el primer elemento [p]^[e] es el mismo que el último elemento; si lo es, luego el segundo con el penúltimo y así sucesivamente ... Si todos son iguales, su lista se puede reducir.
En este ejemplo, marque 2^1*5^1 == 3^2*3^2
; y como no lo es, no se puede reducir.
Probemos [a, b, b, a, b, b]
:
Esto se codifica como
[2^1, 3^2, 2^1, 3^2]
o,
[2, 3, 2, 3] // primes
[1, 2, 1, 2] // exponents
Ahora, comprobamos si 2^1 * 3^2 == 3^2 * 2^1
(primer primer, primer exponente multiplicado por último primer, último exponente, y luego se compara con el segundo frente al penúltimo)
Como esto es válido, es reducible.
Probemos [b, b, b, b, b]
:
Esto puede ser codificada como
[3^5]
o,
[3] // primes
[5] // exponents
Este es un caso especial: si tienes 1 listas de elementos, entonces su la lista original es reducible.
Probemos [b, b, b, b, a]
:
Esto puede ser codificado como
[3^4, 2^1]
o,
[3, 2] // primes
[4, 1] // exponents
Comprobamos si 3^4 == 2^1
, y puesto que no es así, la lista no es reducible.
Probemos [a, b, a, b, a, b]
:
Esto puede ser codificada como
[2^1, 3^1, 2^1, 3^1, 2^1, 3^1]
o,
[2, 3, 2, 3, 2, 3]
[1, 1, 1, 1, 1, 1]
Tratando el procedimiento anterior funciona, porque 2^1 * 3^1 == 3^1 * 2^1 == 2^1 * 3^1
Por lo tanto, el algoritmo haría ser algo como esto:
Codifique todos los números en números primos.
Iterar a través de su lista, haga dos listas y poblar como se describe
Ahora que tiene sus dos listas, p
y e
, ambos tienen una longitud n
hacer esto:
var start = p[0]^e[0] * p[n-1]^e[n-1]
var reducible = true;
for (int i = 0; i < n/2, ++i) :
if ((p[i]^e[i] * p[n-i]^e[n-i]) != start) :
reducible = false;
break;
Nota: Realmente no codifiqué este algoritmo y lo intenté para varias entradas. Es solo una idea Además, si una lista es reducible, a partir de su longitud y longitud de n
, no debería ser demasiado difícil ver cómo reducir la lista original a su forma básica.
Segunda nota: si alguien ve un error anterior, por favor corrígeme. Es posible que nada de esto realmente funcione ya que es tarde y mi concentración no es óptima.
¿Cuál es su regla para la no reducción de '[a, b, b, c]' y '[b, b, b, b, a]'? ¿Y cuál es la intuición? Pregunto porque parece casos especiales de un algoritmo más general. '[b, b]' se reducirá (recursivamente) a '[b]', al igual que '[b, b, b, b] -> [b]' según su tercera regla. –
Lo que está buscando es un algoritmo de compresión de datos. Echa un vistazo a Huffman y la codificación aritmética. –
[a, b, b, c] -> [a, b, b, c] [b, b, b, b, a] -> [b, b, b, b, a] [ b, b] -> [b] Todos estos casos retienen la lista de reproducción original, ya que está girando para siempre. – kiteloop