Estoy trabajando en el software para una máquina que recorta automáticamente las uñas de los pies, de modo que los usuarios puedan simplemente poner sus pies en él y ejecutarlo en lugar de tener que hacerlo manualmente mordiéndolos o usando un cortaúñas.
Es probable que un porcentaje considerable de nuestra base de usuarios potenciales sea judío y, evidentemente, existe una tradición de no recortar las uñas de los pies ( o las uñas de las manos ) en orden secuencial.
Parece haber opiniones discrepantes sobre la aplicación precisa de esta tradición, pero creemos que las siguientes reglas son suficientes para adaptarse a las personas cuyas prácticas religiosas prohíben cortarse las uñas de los pies en orden:
- No se deben cortar dos uñas de los pies adyacentes consecutivamente
- La secuencia de corte en el pie izquierdo no debe coincidir con la secuencia en el pie derecho
- La secuencia de corte en dos corridas consecutivas no debe ser la misma. Las secuencias no deben ser fácilmente predecibles, por lo que codificar una secuencia alterna no funciona.
Así es como hemos decidido numerar los dedos de los pies:
5 4 3 2 1 1 2 3 4 5
Left foot Right foot
He escrito código para resolver el problema, pero el algoritmo utilizado es subóptimo: de hecho, el peor rendimiento de caso es O (∞) . La forma en que funciona es comparable a bogosort . Aquí hay una simplificación de pseudocódigo del código real utilizado:
function GenerateRandomSequence
sequence = Array[5]
foreach (item in sequence)
item = RandomNumberBetween(1,5)
return sequence
function GetToenailCuttingOrder
while (true)
sequence = GenerateRandomSequence()
if (!AllItemsAreUnique(sequence))
continue
if (NoTwoAdjacentItemsHaveConsecutiveNumbers(sequence))
return sequence
do
leftFootSequence = GetToenailCuttingOrder()
rightFootSequence = GetToenailCuttingOrder()
until (leftFootSequence != rightFootSequence &&
leftFootSequence != leftFootSequenceFromLastRun &&
rightFootSequence != rightFootSequenceFromLastRun)
Básicamente, genera secuencias aleatorias y comprueba si cumplen los criterios. Si no cumple con los criterios, comienza de nuevo. No toma una cantidad de tiempo ridículamente larga, pero es muy impredecible.
Me doy cuenta de que la forma en que lo estoy haciendo actualmente es bastante terrible, pero tengo problemas para encontrar una mejor manera. ¿Alguno de ustedes puede sugerir un algoritmo más elegante y eficaz?