Сортировать скремблированный двумерный массив, заполненный числами, поменяв местами соседние числа [закрыто]

9

Двумерный массив размером n × n заполняется n * n числами, начиная с номера 1. Эти числа должны быть отсортированы по строке в порядке возрастания; первый номер строки должен быть больше последнего номера предыдущей строки (наименьшее число из всех (1) будет в [0,0]). Это похоже на 15 головоломки .

Это, например, отсортированный массив размером n = 3 .

1 2 3
4 5 6
7 8 9

вход

Ввод представляет собой скремблированный массив. Может быть любого размера до n = 10. Пример для n = 3:

4 2 3
1 8 5
7 9 6

Вывод

Вывести список свопов, необходимых для сортировки массива. Своп определяется следующим образом : Два смежных номера меняются местами, либо по горизонтали или по вертикали; замена по диагонали не допускается.

Пример вывода для примера выше:

  • Обмен 4 и 1
  • Поменяйте местами 8 и 5
  • Поменяйте местами 8 и 6
  • Обмен 9 и 8

Чем меньше требуется свопов, тем лучше. Время вычислений должно быть возможным.


Вот еще один пример ввода с n = 10:

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

Если я не ошибаюсь, для этого потребуется около 1000-2000 перестановок.

JCarter
источник
Это проблема головоломки, скорости или игры в гольф?
Майкл Кляйн
@MichaelKlein Это загадка.
JCarter
Это забил? Какие диапазоны должны быть обработаны?
Майкл Кляйн
1
@steveverrill Боюсь, что решить пример с n = 10 менее чем за 100 обменов (или даже 1000; но доказать, что я ошибаюсь) совершенно невозможно Тем не менее, число свопов является критерием выигрыша (хотя вычисления должны быть выполнимыми!), Тот, кто придет с решением с наименьшим количеством свопов, выигрывает.
JCarter
1
@JCarter Я думаю, вы хотели сказать, что только смежные номера могут быть заменены?
Quintopia

Ответы:

3

Mathematica, не игра в гольф

towards[a_,b_]:={a,a+If[#==0,{0,Sign@Last[b-a]},{#,0}]&@Sign@First[b-a]};
f[m_]:=Block[{m2=Map[QuotientRemainder[#-1,10]+1&,m,{2}]},
  Rule@@@Apply[10(#1-1)+#2&,#,{2}]&@
    Reap[Table[
      m2=NestWhile[
        Function[{x},x/.(Sow[#];Thread[#->Reverse@#])&[x[[##]]&@@@towards[First@Position[x,i,{2}],i]]]
        ,m2,#~Extract~i!=i&];
      ,{i,Reverse/@Tuples[Range[10],2]}];][[2,1]]]

Пояснение :

Алгоритм похож на «пузырьковую сортировку». Эти 100 чисел приведены в правильном порядке один за другим 1, 11, 21, ..., 91; 2, ..., 92; ...; 10, ..., 100. Сначала они перемещаются вверх / вниз к правильным строкам, а затем перемещаются влево к нужным столбцам.

Функция towardsдает две позиции для обмена. Например, если {5,2}движется к {1,1}, towards[{5,2},{1,1}]дает {{5,2},{5,1}}(двигаться вверх); и towards[{5,1},{1,1}]дает {{5,1},{4,1}}(двигаться влево).


Результаты :

Для тестового случая общее количество обменов составляет 558. Первые несколько обменов,

{1->76,1->34,1->35,1->88,1->41,11->16,11->69,11->46, ...

Для случайной конфигурации общее количество перестановок составляет 558,5 ± 28,3 (1σ).

введите описание изображения здесь

njpipeorgan
источник