Одноколірні арифметичні прогресії


15

Теорема Ван дер Ваердена говорить про це

Для будь-яких заданих цілих чисел rі kє деяка кількість Nтаких, що якщо цілі числа {1, 2, ..., N}кольорові, кожне з одним r різним кольором, то kв арифметичній прогресії є принаймні цілі числа, одного кольору. Найменше таким Nє число Ван дер Ваердена W(r, k).

Ваша мета - обчислити число Ван-дер-Вайрдена з W(r, k)урахуванням позитивних цілих чисел rта k. Виграє найменше байт.

Слідкуйте за тим, щоб ця функція зростала надзвичайно швидко і вимагає трудомістких обчислень. Навіть W(4, 4)невідомо. Ви можете припустити, що ваш код працює на ідеальному комп'ютері з необмеженими ресурсами (час, пам'ять, глибина стека тощо). Ваш код теоретично повинен дати правильну відповідь навіть для значень, на які відповідь не відома.

Вбудовані модулі, які обчислюють цю функцію, заборонені.

Приклад

Для r = 2кольорів та прогресій довжини k = 3існує 8послідовність довжини , яка уникає такої прогресії, тобто 3елементи однакового розміру одного кольору:

B R R B B R R B

Але, такої 9послідовності довжини немає , так W(2, 3) == 9. Наприклад,

R B B R B R R B R
  ^     ^     ^      

містить 3показану арифметичну прогресію довжини - однаковий колір.

Тестові справи

Можливо, ви зможете перевірити лише невеликі випадки.

+-----+-----+-----+-----+-----+-----+------+
|     | k=1 | k=2 | k=3 | k=4 | k=5 | k=6  |
+-----+-----+-----+-----+-----+-----+------+
| r=1 |   1 |   2 |   3 |   4 |   5 |    6 |
| r=2 |   1 |   3 |   9 |  35 | 178 | 1132 |
| r=3 |   1 |   4 |  27 | 293 |     |      |
| r=4 |   1 |   5 |  76 |     |     |      |
+-----+-----+-----+-----+-----+-----+------+

Відповіді:


7

Python 3.5, 125 124 119 байт

f=lambda r,k,*L:any(L[:x*k:x]==k*(*{*L[:x*k:x]},)for x in range(1,len(L)+1))*len(L)or max(f(r,k,i,*L)for i in range(r))

Це смішно, тому що в ході гольфу це програма насправді стала більш ефективною. Все, що перевищує f(2,4)абоf(3,3) по- , як і раніше займає назавжди, хоча.

Пояснення

Початкова версія перевіряла, чи містить послідовність прогресування довжини k, намагаючись усі можливі стартові індекси та кроки.

def f(r,k,L=[]):
 for i in range(len(L)):
  for j in range(len(L)):
   if len(set(L[i::j+1]))==1 and len(L[i::j+1])==k:
    return len(L)
 return max(f(r,k,L+[i])for i in range(r))

Версія для гольфу повинна лише спробувати всі можливі кроки, оскільки вона створює нові елементи послідовності. Thex*kКришка піклуватися про випадки , як[0, 0, 1] , яка містить прогресію довжини 2 , але не задовольняла б унікальність перевірки розкритою.

Щодо чека

L[:x*k:x]==k*(*{*L[:x*k:x]},)

На першому проході версії для гольфу, коли Lвін порожній, len(L)дорівнює 0. Таким чином, друга половина orзаповіту завжди буде виконана. Після цього Lє не порожнім, так {*L[:x*k:x]}(що якраз для Python 3.5 дляset(L[:x*k:x]) ) буде принаймні один елемент.

Оскільки L[:x*k:x]може мати щонайбільше kелементів, а для Lнепустого k*(*{*L[:x*k:x]},)має принаймні kелементи, два можуть бути рівними лише тоді, коли kв обох є точно такі елементи. Для цього {*L[:x*k:x]}має бути рівно один елемент, тобто у нас лише один колір у процесі прогресування.

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