N皇后拼图


17

(尽管有超过60个问题标记为,但我们没有简单的n皇后挑战。)

在国际象棋中,N-皇后之谜的描述如下:给定n x n棋盘和n皇后,将皇后排列在棋盘上,以使没有两个皇后相互威胁。以下是n = 8从Wikipedia借来的的示例解决方案。

Wikipedia的8女王示例解决方案

或者,在ASCII渲染中:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

这里的挑战将是输入n和输出n-Queens难题解决方案的ASCII表示形式。由于存在多个可能的解决方案(例如,至少是旋转或反射),因此您的代码仅需要输出任何有效的解决方案。

输入项

n具有n >= 4 任何方便格式的单个正整数。(n = 2和n = 3没有解,并且n = 1很小,因此将其排除在外)

输出量

如上所述,解决了N-queens难题的结果的ASCII表示形式。您可以选择任何两个不同的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


1
您能否给出奇数输入的测试用例?
Kritixi Lithos'7

@Cowsquack添加了n = 7示例
AdmBorkBork '17

1
@KeyuGan像MATL答案一样的东西吗?是的,很好。
AdmBorkBork

2
@JonathanAllan只要程序在有限的时间内以概率一(所有提交的标准)结束,就没有这种排除的意图。
AdmBorkBork

Answers:


5

MATL33 32 27字节

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

在线尝试!

半强力,非确定性方法:

  1. 生成行位置的随机排列
  2. 生成列位置的随机排列
  3. 检查没有皇后共享对角线或反对角线
  4. 如有必要,请重复。

所获得的解是随机的。如果再次运行该代码,则可能会得到其他有效的配置。运行时间也是随机的,但是最长的测试用例(n = 10)大部分时间在TIO中大约需要30秒才能完成。


我不确定这是否可以作为解决方案,因为它并不总是能给出正确的答案。
junkmail

1
@junkmail嗯?有没有这样的事情正确答案,因为有一个几种解决方案(如通过挑战说明)。代码总是给出一个正确的答案,只是不一样的每一次
路易斯Mendo

从理论上讲,该程序可以任意运行多次,但仍然无法给出答案。
junkmail

1
@junkmail但它以有限的概率在有限的时间内完成
Luis

1
@JamesHollis我不同意。这可能会使某些排列比其他排列更有可能,但不会阻止任何排列的出现。因此最终将找到解决方案。此外,假定随机生成器是理想的通常被接受
Luis Mendo

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)时间内打印解决方案。


1
我不清楚循环重复n次的O(1)怎么可能。所有这些计算如何总是始终如一地完成?
poi830

1
@ poi830我的意思是每行O(1)计算时间以确定女王的位置。
Orlp

您不能通过为创建新变量来节省一些n/2吗?
Jeffmagma

建议n-=o=n%2;for(y=n+o;y--;)不要使用o=n%2;n-=o;for(y=0;y<n+o;++y)
ceilingcat '19

2

Mathematica,103 108 110 117 个字节

-5个字节用于DuplicateFreeQ->E!=##&@@@

-7个字节用于ReplacePart[Array[],]->SparseArray[]

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

返回一个二维数组。计算需要2.76秒,f[6]而需要135 秒f[7]。(在当前版本中,-变得0Q1

输出

该算法类似于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链接。


由于此代码不是您的代码,您可以将其转换为社区Wiki吗?(只需单击编辑窗口下方的“社区Wiki”按钮)
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吗?
暴民埃里克(Erik the Outgolfer)'17年

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

在线尝试!

这是或多或少基于所述℃溶液通过orlp

说明

突出显示执行路径的源代码

*从标准输入中读取皇后数q,并计算两个变量以备后用:n = q - q%2,然后hn = n/2
*启动主循环,将r的行号从q迭代到0,并在循环开始时递减,从而开始循环,因此第一个rq减去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;

整数除以N2。(还可以将结果包装起来,:;以便更轻松地锚定模式。)

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

如果循环索引等于N/2*2,则仅留那么多空格。

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

如果N/2是3的倍数,则取两倍的循环索引加1,取模N/2*2+1

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

否则,将循环索引(N/2-1)加倍,再在板的下半部分加上3,以模为模N/2*2

( +)%\1?

实际执行模运算。


0

木炭,44字节

Nθ≔÷θ²ηEθ◧Q⊕⎇⁼ι⊗ηι⎇﹪η³﹪⁺⁺⊗ι⊖η׳¬‹ιη⊗η﹪⊕⊗ι⊕⊗η

在线尝试!链接是详细版本的代码。@orlp出色的C答案的另一个端口。


0

APL(Dyalog Unicode),18字节 SBCS

n从stdin进行完整程序提示。将空格分隔的解决方案打印到stdout,·用于空正方形和皇后区。

CY'dfns'
queens

在线尝试!

⎕CY'dfns'Ç运算ÿ的“DFN和”库

 从stdin获取输入

queens 找到所有真正独特的皇后区解决方案(无反射或旋转)

 选择第一个解决方案


0

J,49个字节

i.=/0({(1-.@e.,)@(([:(=#\){.|@-}.)\."1)#])!A.&i.]

在线尝试!

通过测试长度为n的所有排列进行暴力破解。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.