Я работаю над программным обеспечением для машины, которая будет автоматически обрезать ногти на ногах, чтобы пользователи могли просто положить в нее ноги и запустить ее, вместо того, чтобы делать это вручную, кусая их или используя кусачки для ногтей.
Значительный процент нашей потенциальной базы пользователей, скорее всего, будут евреями, и, очевидно, существует традиция не стричь ногти на ногах ( или ногтях ) в последовательном порядке.
Похоже, существует особое мнение о точном применении этой традиции, но мы считаем, что следующих правил достаточно, чтобы приспособить людей, чьи религиозные обычаи запрещают стрижку ногтей на ногах, по порядку:
- Нельзя обрезать два соседних ногтя подряд
- Последовательность резания на левой ступне не должна совпадать с последовательностью на правой ступне.
- Последовательность резки в двух последовательных проходах не должна быть одинаковой. Последовательности не должны быть легко предсказуемыми, поэтому жесткое кодирование чередующейся последовательности не работает.
Вот как мы решили пронумеровать пальцы ног:
5 4 3 2 1 1 2 3 4 5
Left foot Right foot
Я написал код для решения проблемы, но используемый алгоритм не оптимален: на самом деле, производительность в худшем случае составляет O (∞) . Принцип его работы сравним с богосортом . Вот упрощенный псевдокод фактически используемого кода:
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)
По сути, он генерирует случайные последовательности и проверяет, соответствуют ли они критериям. Если он не соответствует критериям, он начинается заново. Это не занимает до смешного много времени, но очень непредсказуемо.
Я понимаю, что то, что я делаю сейчас, довольно ужасно, но у меня проблемы с поиском лучшего способа. Может ли кто-нибудь из вас предложить более элегантный и производительный алгоритм?