Развернуть проблему школьницы Киркмана


22

Для тех из вас, кто незнаком, проблема школьницы Киркмана выглядит следующим образом:

Пятнадцать юных леди в школе выходят три в ряд в течение семи дней подряд: необходимо устраивать их ежедневно, чтобы двое не ходили дважды в ряд.

Мы можем посмотреть на это как вложенный список 3 на 5 (или матрицу):

[[a,b,c]
 [d,e,f]
 [g,h,i]
 [j,k,l]
 [m,n,o]]

По сути, цель исходной задачи состоит в том, чтобы найти 7 различных способов упорядочить вышеуказанную матрицу, чтобы две буквы никогда не разделяли строку более одного раза . Из MathWorld (ссылка выше) мы находим это решение:

[[a,b,c]   [[a,d,h]   [[a,e,m]   [[a,f,i]   [[a,g,l]   [[a,j,n]   [[a,k,o]
 [d,e,f]    [b,e,k]    [b,h,n]    [b,l,o]    [b,d,j]    [b,i,m]    [b,f,g]
 [g,h,i]    [c,i,o]    [c,g,k]    [c,h,j]    [c,f,m]    [c,e,l]    [c,d,n]
 [j,k,l]    [f,l,n]    [d,i,l]    [d,k,m]    [e,h,o]    [d,o,g]    [e,i,j]
 [m,n,o]]   [g,j,m]]   [f,j,o]]   [e,g,n]]   [i,k,n]]   [f,h,k]]   [h,l,m]]

А что, если бы было другое количество школьниц? Может ли быть восьмой день? Это наш вызов.

В этом случае нет † † , но это не обязательно для других размеров массива
† † Мы можем легко показать это, поскольку aпоявляются в ряду с каждой другой буквой.


Соревнование:

Учитывая ввод измерений (строк, чем столбцов) массива школьниц (то есть 3 x 5, 4 x 4или [7,6], [10,10]и т. Д.), Выведите максимально возможный набор «дней», который соответствует требованиям, указанным выше.

Ввод:
Размеры для массива школьниц (любая разумная форма ввода, которую вы хотите).

Вывод:
максимально возможная серия массивов, отвечающая вышеуказанным требованиям (любая разумная форма).

Тестовые случаи:

Input:  [1,1]
Output: [[a]]

Input:  [1,2]
Output: [[a,b]]

Input:* [2,1]
Output: [[a]
         [b]]

Input:  [2,2]
Output: [[a,b]  [[a,c]  [[a,d]
         [c,d]]  [b,d]]  [b,c]]

Input:  [3,3]
Output: [[a,b,c]  [[a,d,g]  [[a,e,i]  [[a,f,h]
         [d,e,f]   [b,e,h]   [b,f,g]   [b,d,i]
         [g,h,i]]  [c,f,i]]  [c,d,h]]  [c,e,g]]

Input:  [5,3]
Output: [[a,b,c]   [[a,d,h]   [[a,e,m]   [[a,f,i]   [[a,g,l]   [[a,j,n]   [[a,k,o]
         [d,e,f]    [b,e,k]    [b,h,n]    [b,l,o]    [b,d,j]    [b,i,m]    [b,f,g]
         [g,h,i]    [c,i,o]    [c,g,k]    [c,h,j]    [c,f,m]    [c,e,l]    [c,d,n]
         [j,k,l]    [f,l,n]    [d,i,l]    [d,k,m]    [e,h,o]    [d,o,g]    [e,i,j]
         [m,n,o]]   [g,j,m]]   [f,j,o]]   [e,g,n]]   [i,k,n]]   [f,h,k]]   [h,l,m]]

There may be more than one correct answer. 

* Спасибо @Frozenfrank за исправление тестового примера 3 : если есть только один столбец, может быть только один день, поскольку порядок строк не имеет значения.

Это соревнование по - выигрывает самый короткий ответ.


Это как-то связано с конечными проективными плоскостями, или я думаю о другой проблеме?
Нейл

@ Нейл, я понятия не имею. Боюсь, у меня нет права на это отвечать. ;-)
Скотт Милнер

Есть ли ограничение по времени?
Artyer

@Artyer Нет, но я хотел бы иметь возможность протестировать код ...
Скотт Милнер

2
@Neil, это было забавное чтение википедии.
Волшебная Осьминог Урна

Ответы:


12

Mathematica, 935 байт

Inp={5,4};L=Length;T=Table;ST[t_,k_,n_]:=Binomial[n-1,t-1]/Binomial[k-1,t-1];H=ToExpression@Alphabet[];Lo=Inp[[1]]*Inp[[2]];H=H[[;;Lo]];Final={};ST[2,3,12]=4;ST[2,4,20]=5;If[Inp[[2]]==1,Column[Partition[H,{1}]],CA=Lo*Floor@ST[2,Inp[[2]],Lo];While[L@Flatten@Final!=CA,Final={};uu=0;S=Normal[Association[T[ToRules[H[[Z]]==Prime[Z]],{Z,L@H}]]];PA=Union[Sort/@Permutations[H,{Inp[[2]]}]];PT=Partition[H,Inp[[2]]];While[L@PA!=0,AppendTo[Final,PT];Test=Flatten@T[Times@@@Subsets[PT[[X]],{2}]/.S,{X, L@PT}];POK=T[Times@@@Subsets[PA[[Y]],{2}]/.S,{Y,L@PA}];Fin=Select[POK,L@Intersection[Test,#]==0&];Facfin=T[FactorInteger[Fin[[V]]],{V,L@Fin}];end=T[Union@Flatten@T[First/@#[[W]],{W,L@#}]&[Facfin[[F]]],{F,L@Facfin}]/.Map[Reverse,S];PA=end;PT=DeleteDuplicates[RandomSample@end,Intersection@##=!={}&];If[L@Flatten@PT<L@H,While[uu<1000,PT=DeleteDuplicates[RandomSample@end,Intersection@##=!={}&];If[L@Flatten@PT==L@H,Break[],uu++]]]]];Grid@Final]


это для 26 дам макс

РЕДАКТИРОВАТЬ
Я сделал некоторые изменения, и я думаю, что это работает! Код прямо сейчас решает [5,4] (что является «проблемой социальных игроков в гольф») и получает результат через несколько секунд. Однако проблема [5,3] сложнее, и вам придется подождать 10-20 минут, но вы получите правильную комбинацию на все дни. Для более простых случаев это очень быстро.

в любом случае, вы можете попробовать и посмотреть результаты.
Попробуйте
скопировать и вставить его онлайн, используя ctrl-v,
нажмите shift + enter, чтобы запустить код, который
вы можете изменить в начале кода -> Inp = {5,4}
запустить кодировать несколько раз, чтобы получить различные перестановки


Хотя это впечатляет и делает большой прогресс в решении проблемы, оно все еще не завершено. Хотя он работает для небольших тестовых случаев, он не может решить более крупные [5,3]тесты , включая тестовый пример, на котором основана вся эта проблема. Кроме того, это может быть больше в гольфе; Есть несколько имен переменных, которые больше, чем они должны быть, и некоторые функции могут быть сокращены с помощью @или инфиксной записи. Я надеюсь, что вы продолжите работать, хотя!
Скотт Милнер

спасибо за проверку. Я постараюсь сначала сделать эту работу, а затем
J42161217

1
Вы должны быть в состоянии сэкономить много байтов, сделав ваши имена переменных отдельными буквами, и присвоив переменным некоторые функции, которые вы используете более одного раза, и заменив функции этими переменными :)
numbermaniac

2
@numbermaniac Просто заменив имена переменных, я смог получить его 914. Это должно быть в гольф примерно до 850.
Скотт Милнер

3
Я исправил контрольный пример. Прежде всего, я хочу, чтобы это сработало. Вот почему я еще не играл в гольф. Спасибо за все ваши комментарии. Я думаю, что теперь это готово.
J42161217
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.