Ви можете перемогти Білла Гейтса?


13

Сортування млинців - це розмовний термін для математичної проблеми сортування невпорядкованої стопки млинців за розміром, коли шпатель можна вставити в будь-яку точку стопки і використовувати для перегортання всіх млинців над нею. Номер млинця P (n) - мінімальна кількість фліп, необхідна для n млинців. 1

У 1979 році молодий Білл Гейтс і Крістос Пападімітріу написали документ, що підтверджує верхню межу P (n) = (5n + 5) / 3 . 2

Я думаю, що можна припустити, що Гейтс (та / або Пападімітріу) написав програму для сортування млинців, використовуючи алгоритм, який вони розробили (можливо, пізніше 1979 року). Оскільки Гейтс був кваліфікованим програмістом, вони, ймовірно, намагалися переграти цей код так добре, як могли, але розмір вихідного коду не є загальнодоступним (AFAIK).

Виклик:

Створіть функцію / програму, яка виконує сортування млинців, де максимальна кількість обертів не перевищує межу, знайдену Гейтсом та Пападімітріу. 3 Ви можете вибрати, якщо ви хочете, щоб список збільшувався чи спадаючий, якщо він буде послідовним.

Можна припустити, що n <50 . Ви повинні обмежити кількість фліп (до деяких випадково вибраних n- значень):

 n   P(n)
38   65
49   83
50   85

Вихід повинен бути положенням шпателя перед кожним поворотом. Вихід може бути нульовим або одноіндексованим, і ви можете вибрати, якщо рахувати зверху чи знизу.

Додаткові правила:

  • Час виконання має бути детермінованим
  • Немає фіксованого часового обмеження, але ви повинні мати можливість надати вихід для списку з 50 елементами

Списки тестів:

Я не можу надати найскладніші списки (якщо так, я б написав документ, а не виклик), тому я надам кілька випадкових списків чисел, на яких можна перевірити свої функції / програми. Я можу додати інших, якщо виявиться ці списки там, де "просто".

9, 63, 62, 75, 45, 78, 59, 75, 69, 3, 28, 94, 51, 10, 45, 93, 97, 80, 72, 36, 80, 88, 30, 93, 84, 80, 17, 31, 6, 80, 76, 91, 9, 76, 38, 33, 22, 15, 45, 46, 15, 98, 2, 56, 90, 27, 27, 26, 69, 25
...
74, 89, 57, 52, 70, 96, 16, 5, 77, 84, 54, 13, 90, 64, 31, 80, 3, 25, 13, 19, 13, 34, 1, 79, 35, 43, 4, 19, 82, 29, 48, 95, 97, 28, 45, 62, 64, 82, 70, 34, 38, 15, 51, 83, 21, 66, 4, 42, 74, 84
...
62, 73, 7, 90, 83, 18, 12, 35, 72, 71, 99, 67, 87, 62, 65, 70, 14, 72, 55, 92, 87, 3, 7, 4, 4, 95, 49, 25, 4, 18, 49, 39, 26, 1, 45, 64, 23, 66, 39, 17, 33, 24, 58, 72, 77, 46, 99, 71, 10, 21

Сподіваємось, Білл Гейтс і Пападімітріу побачать це завдання і нададуть їх код, щоб ми могли визначити, чи справді ви їх перевершили.

Знайдено 3 кращих верхніх меж, але про них вам не потрібно дбати.


Пов’язані , але не дублікати. Тут відповіді не працюватимуть.
Стюі Гріффін

Тоді я тоді використовував BFS у своєму рішенні, він все одно повинен працювати тут (з невеликим оновленням), щоб знайти рішення з мінімальною кількістю фліп.
миль

@miles тоді сміливо публікуйте це. Я не детально перебирав усі відповіді, але більшість просто використовував наївний підхід.
Стюі Гріффін

Відповіді:


4

Python 2 (PyPy) , 238 235 222 байт

a=input();n=len(a);r=range(n);a=zip(a,r);a=map(sorted(a).index,a)+[n]
def s(u,m):
 if m<1:return[0]
 for k in r:
  v=u[k::-1]+u[k+1:]
  if sum(1<abs(v[i]-v[i+1])for i in r)<m:
   p=s(v,m-1)
   if p:return[k]+p
print s(a,5*n/3)

* (2 пробіли = вкладка)

Спробуйте в Інтернеті!

Збережено 13 байт запозичення методу ранжирування списку .

DFS з простим евристикою, який перевіряє, чи відокремлює фліп пари "млинців", які були б суміжними при сортуванні. Сортуйте його у порядку зростання. Вихід 0-індексується зліва, де 0 перевертає перші 2 тощо. Кількість застосованих рухів - це те, (5/3)*n+1 < 5/3*(n+1)де (18/11)*n < (5/3)*n+1 < 5/3*(n+1)і (18/11)*nє більш чітка верхня межа в 2009 році .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.