N-Queens Puzzle

17

(Несмотря на более 60 вопросов, помеченных как , у нас нет простой задачи для n-ферзей.)

В шахматах головоломка N-Queens описывается следующим образом: учитывая n x nшахматную доску и nферзей, расположите ферзей на шахматной доске так, чтобы никакие две королевы не угрожали друг другу. Ниже приведен пример решения n = 8, заимствованный из Википедии.

Пример решения с 8 ферзями из Википедии

Или в рендеринге ASCII:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

Задача здесь будет заключаться в том, чтобы взять nи вывести ASCII-представление решения nголоволомки -Queens. Поскольку существует более одного возможного решения (например, как минимум, вращение или отражение), вашему коду нужно только вывести любое допустимое решение.

вход

Один положительное целое число nс n >= 4 в любом удобном формате . (n = 2 и n = 3 не имеют решений, а n = 1 тривиально, поэтому они исключаются)

Выход

Результирующее ASCII-представление решения головоломки N-Queen, как описано выше. Вы можете выбрать любые два различных значения ASCII для представления пробелов и королев. Опять же, это может быть выведено в любом подходящем формате (одна строка, список строк, массив символов и т. Д.).

правила

  • Начальные или завершающие символы новой строки или пробелы являются необязательными, а также пробелы между символами, если сами символы выстроены правильно.
  • Вы можете либо использовать алгоритм для вычисления возможных позиций, либо использовать явный стиль решения «ступеньки», в зависимости от того, что лучше для вашего кода.
  • Либо полная программа или функция приемлемы. Если функция, вы можете вернуть вывод, а не распечатать его.
  • Если возможно, укажите ссылку на среду онлайн-тестирования, чтобы другие люди могли опробовать ваш код!
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

Примеры

n=4
xQxx
xxxQ
Qxxx
xxQx

n=7
xxQxxxx
xxxxxxQ
xQxxxxx
xxxQxxx
xxxxxQx
Qxxxxxx
xxxxQxx

n=10
xxxxQxxxxx
xxxxxxxxxQ
xxxQxxxxxx
xxxxxxxxQx
xxQxxxxxxx
xxxxxxxQxx
xQxxxxxxxx
xxxxxxQxxx
Qxxxxxxxxx
xxxxxQxxxx
AdmBorkBork
источник
1
Связанный.
полностью человек
1
Не могли бы вы дать тестовые случаи для нечетных входов?
Критиси Литос
@Cowsquack Добавлен пример n = 7
AdmBorkBork
1
@KeyuGan Что-то вроде ответа в MATL? Да, это нормально.
AdmBorkBork
2
@JonathanAllan Такое исключение не предназначалось, если программа завершается за конечное время с вероятностью один (стандарт для всех представлений).
AdmBorkBork

Ответы:

5

MATL , 33 32 27 байт

`x,GZ@]1Z?tt!P!,w&TXds]h1>a

Попробуйте онлайн!

Полубортовая сила, недетерминированный подход:

  1. Генерация случайной перестановки позиций строк
  2. Генерация случайной перестановки позиций столбцов
  3. Убедитесь, что ни одна королева не имеет диагонали или анти-диагонали
  4. Повторите при необходимости.

Полученное решение является случайным. Если вы снова запустите код, вы можете получить другую допустимую конфигурацию. Время выполнения также является случайным, но самый длинный тестовый случай ( n = 10) заканчивается в течение 30 секунд в TIO большую часть времени.

Луис Мендо
источник
Я не уверен, что это считается решением, учитывая, что оно не всегда дает правильный ответ.
junkmail
1
@ junkmail А? Там нет такого понятия , как на правильный ответ, так как там несколько решений (как указано на вызов). Код всегда дает более правильный ответ, только не то же самое каждый раз
Luis Mendo
Теоретически возможно, что программа будет работать произвольно много раз и все еще не даст ответа.
junkmail
1
@junkmail Но это заканчивается за конечное время с вероятностью один
Луис Мендо
1
@JamesHollis Я не согласен. Это может сделать некоторые перестановки более вероятными, чем другие, но это не помешает появлению любой перестановки. Таким образом, решение в конечном итоге будет достигнуто. И кроме того, предположим, что генератор случайных чисел является идеальным, обычно принимается
Луис Мендо
5

C, 114 байтов

Q(n,o,y){o=n%2;n-=o;for(y=0;y<n+o;++y)printf("%*c\n",y<n?o+n-(n+y%(n/2)*2+(n%6?y<n/2?n/2-1:2-n/2:y<n/2))%n:0,81);}

Напрямую печатает решение за O (1) раз.

orlp
источник
1
Мне не ясно, как это может быть O (1) с циклом, повторяющимся n раз. Как все эти расчеты всегда можно выполнять за постоянное время?
poi830
1
@ poi830 Я имею в виду O (1) время вычисления на строку, чтобы определить положение королевы.
orlp
Вы не могли бы сохранить несколько, создав новую переменную для n/2?
Джеффмагма
Предлагаю n-=o=n%2;for(y=n+o;y--;)вместоo=n%2;n-=o;for(y=0;y<n+o;++y)
floorcat
2

Математика, 103 108 110 117 байтов

-5 байт для DuplicateFreeQ->E!=##&@@@

-7 байт для ReplacePart[Array[],]->SparseArray[]

SparseArray[Thread@#&@@Select[Permutations@Range@#~Tuples~2,And@@(E!=##&@@@{#-#2,+##})&@@#&]->1,{#,#}]&

Вернуть 2D-массив. Требуется 2,76 с для расчета f[6]и 135 с f[7]. (В текущей версии, -становится 0и Qдо 1.

выход

Алгоритм аналогичен ответу MATL, но здесь код полностью грубый.

Кейу Ган
источник
1

C - 222 байта

v,i,j,k,l,s,a[99];main(){for(scanf("%d",&s);*a-s;v=a[j*=v]-a[i],k=i<s,j+=(v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[l^v?(l^j)&1:2])&&++l||a[i]<s&&v&&v-i+j&&v+i-j))&&!(l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&++a[--i]);}

Код не мой, а из IOCCC . Надеюсь, я не нарушаю никаких правил. Кроме того, здесь отображаются все решения для N от 4 до 99. Я постараюсь получить ссылку TIO позже.

QuaerendoInvenietis
источник
Поскольку этот код не ваш, не могли бы вы преобразовать его в вики сообщества? (просто нажмите кнопку под окном редактирования с надписью "Сообщество вики")
caird coinheringaahing
Привет QuaerendoInvenietis и добро пожаловать в PPCG. Как написано в настоящее время, кажется, что в качестве входных и выходных данных это конкретное число не принимает.
AdmBorkBork
1

Желе , 24 21 байт

,JŒc€IF€An/PC
ẊÇ¿=þRG

Попробуйте онлайн!

Предполагая, что каждая королева размещается в отдельных строках, нам нужно только найти индексы столбцов, чтобы разместить каждую королеву, чтобы избежать конфликтов, которые можно найти, генерируя случайную перестановку [1, 2, ..., n] и проверяя ее.

объяснение

,JŒc€IF€An/PC  Helper. Input: permutation of [1, 2, ..., n]
 J             Enumerate indices, obtains [1, 2, ..., n]
,              Join
  Œc€          Find all pairs in each
     I         Calculate the difference of each pair
      F€       Flatten each
        A      Absolute value
               (We now have the distance in column between each queen and
                the distance in rows between each queen. If they are unequal,
                the queens do not conflict with each other)
         n/    Reduce using not-equals
           P   Product, returns 1 only if they are all unequal
            C  Complement
               Returns 1 when there is a conflict, else 0

ẊÇ¿=þRG  Main.  Input: n
Ẋ        Shuffle (When given an integer, it will shuffle [1, 2, ..., n])
 Ç¿      While the helper returns 1, continue shuffling
     R   Range, gets [1, 2, ..., n]
   =þ    Equality table (Generates the board as a matrix)
      G  Pretty-print the matrix
миль
источник
Вы не можете использовать Œc€вместо œc€2-1?
Эрик Outgolfer
1

Python 3, 204 189 байт

import itertools as p
n=int(input())
r=range(n)
b='.'*(n-1)+'Q'
for c in p.permutations(r):
 if len(set((x*z+c[x],z)for x in r for z in[1,-1]))==n+n:[print(*(b[x:]+b[:x]))for x in c];break

Перебор грубой силы по всем перестановкам. Я мог бы удалить * и распечатать список пониманий, но они выглядят ужасно.

Выход:

10
Q . . . . . . . . .
. . Q . . . . . . .
. . . . . Q . . . .
. . . . . . . Q . .
. . . . . . . . . Q
. . . . Q . . . . .
. . . . . . . . Q .
. Q . . . . . . . .
. . . Q . . . . . .
. . . . . . Q . . .

Слегка разгульный

import itertools as p
n=int(input())
r=range(n)
b='.'*(n-1)+'Q'
for c in p.permutations(r):
    if len(set( (x*z+c[x],z) for x in r for z in[1,-1] )) == n+n:
        [print(*(b[x:] + b[:x])) for x in c]
        break
Джеймс Холлис
источник
1

Befunge, 122 байта

&::2%-v>2*00g++00g%00g\-\00g\`*4>8#4*#<,#-:#1_$55+"Q",,:#v_@
/2p00:<^%g01\+*+1*!!%6g00-2g01\**!!%6g00-g012!:`\g01:::-1<p01

Попробуйте онлайн!

Это более или менее основано на C-решении от orlp .

объяснение

Исходный код с выделенными путями исполнения

*Считайте количество ферзей q из stdin и вычислите две переменные для последующего использования: n = q - q%2и hn = n/2
*Запустите основной цикл, повторяя r , номер строки, из q до 0, с уменьшением в начале цикла, поэтому первый r is q минус 1.
*Рассчитайте смещение ферзя в каждой строке по следующей формуле:

offset = (n - (
  (hn <= r) * (2 - hn) * !!(n % 6) + 
  (hn > r) * ((hn - 2) * !!(n % 6) + 1) + 
  (y % hn * 2) + n
) % n) * (n > r)

*Выведите смещенные пробелы для отступа позиции ферзя для текущей строки, плюс еще один пробел только потому, что это облегчает цикл вывода.
*ВывестиQ для королевы, а затем новую строку, чтобы перейти к следующей строке.
*Проверьте, что r равно нулю, и в этом случае мы достигли конца доски и можем выйти, в противном случае мы повторим основной цикл снова.

Джеймс Холдернесс
источник
0

Haskell , 145 байт

Очевидный подход грубой силы:

b=1>0
t[]=b
t(q:r)=all(/=q)r&&foldr(\(a,b)->(abs(q-b)/=a&&))b(zip[1..]r)&&t r
q n|y<-[1..n]=(\q->(' '<$[1..q])++"Q")<$>[x|x<-mapM(\_->y)y,t x]!!0

Попробуйте онлайн!

ბიმო
источник
0

Сетчатка , 136 байт

.+
$* 
 
$_;$`Q¶
( +)\1( ?);
:$1;
:( +);\1\1
$1$1
:((   )+);( *)
 $1$1% $3$3
: ( +);( \1)?( *)
 $1 $1%$#2$* $#2$* $#2$* $1$3$3
( +)%\1?

Попробуйте онлайн! Порт @ orlp отличный ответ C. Объяснение:

.+
$* 

Преобразовать в одинарные, используя пробелы (после пробела есть пробел *).

$_;$`Q¶

Создать Nстроки сN пробелами a ;, затем 0..N-1пробелами, затем a Q. Остальные этапы применяются ко всем строкам.

( +)\1( ?);
:$1;

Целочисленное деление Nна 2. (Также оберните результат, :;чтобы упростить привязку шаблонов.)

:( +);\1\1
$1$1

Если индекс цикла равен N/2*2, то просто оставьте столько пробелов.

:((   )+);( *)
 $1$1% $3$3

Если N/2 кратно 3, то возьмите удвоенный индекс цикла плюс один, по модулю N/2*2+1.

: ( +);( \1)?( *)
 $1 $1%$#2$* $#2$* $#2$* $1$3$3

В противном случае возьмите удвоенный индекс цикла плюс (N/2-1) плюс 3 в нижней половине доски, по модулю N/2*2.

( +)%\1?

На самом деле выполнить операцию по модулю.

Нил
источник
0

APL (Dyalog Unicode) , 18 байт SBCS

Полная программа подсказки nот стандартного ввода. Выводит разделенное пробелами решение в стандартный вывод, используя ·для пустых квадратов и для королев.

CY'dfns'
queens

Попробуйте онлайн!

⎕CY'dfns'C op y в «dfns» библиотека

 получить ввод от стандартного ввода

queens найти все действительно уникальные решения Queens (без отражений и поворотов)

 выбрать первое решение

Адам
источник