Pokojowe współistniejące armie

15

W grze w szachy istnieje element zwany królową, który może atakować każdy inny element, który znajduje się w tym samym rzędzie, kolumnie lub po przekątnej. W szachach występują zazwyczaj dwie boki, czarno-biały, z których każdy należy do jednej z drużyn. Kawałki nie mogą atakować sztuk należących do tej samej drużyny.

Twoim celem jest znalezienie największych pokojowych współistniejących armii na kwadratowej planszy. Jest to największa liczba czarnych i białych królowych, które mogą zmieścić się na planszy, tak że żadne dwie królowe nie mogą się nawzajem atakować, a liczba czarnych królowych jest równa liczbie białych królowych.

Otrzymasz jako dane wejściowe długość boku kwadratowej planszy i powinieneś podać liczbę największych największych pokojowych armii, które mogą zmieścić się na tej planszy.

To jest więc obowiązują standardowe reguły dla tagu.

OEIS A250000

Te przypadki testowe obejmują wszystkie znane odpowiedzi. Twoje rozwiązanie powinno być uogólnioną odpowiedzią, która przy wystarczającej mocy obliczeniowej i czasie może obliczyć rozwiązanie dla dowolnej wartości wejściowej.

1: 0
2: 0
3: 1
4: 2
5: 4
6: 5
7: 7
8: 9
9: 12
10: 14
11: 17
12: 21
13: 24
Post Rock Garf Hunter
źródło
Po przeczytaniu łącza OEIS nie jestem pewien, czy istnieją znane rozwiązania dla dowolnej długości boku.
Kelly Lowder
5
@ KellyLowder Zawsze możesz brutalnie zmusić to!
musicman523
2
@ musicman523, lol coś w rodzaju 3 ^ (6 ^ 2) lub 10 ^ 17 możliwych stanów dla płyty 6x6.
Kelly Lowder
5
@ KellyLowder Nie powiedziałem, że to będzie szybkie: P
musicman523
Przycinanie przyspieszy.
CalculatorFeline

Odpowiedzi:

8

C, 476 bajtów, iterujące DFS białe królowe, O (2 n 2 )

#define R return
#define Z(q)for(j=q;j<I;j++)
#define Q(q)memset(q,0,4*J);
#define U(q)S(w[k]/I q j,w[k]%I+j)
int*c,*w,*Y,j,k,r,I,J,m;T(i,j){R i*I+j;}S(x,y){x>=0&&x<I&&y>=0&&y<I?Y[T(x,y)]=1:0;}g(l){int i;if(l==m){Q(Y)for(k=m;k--;){Z(0)Y[T(w[k]/I,j)]=Y[T(j,w[k]%I)]=1;Z(-I)U(+),U(-);}for(r=k=J;k--;)r-=Y[k];R r>=m;}for(i=!l?0:w[l-1]+1;i<J;i++){if(!c[i]){c[i]=1;w[l]=i;if(g(l+1))R 1;c[i]=0;}}R 0;}f(s){I=s;J=I*I;int C[J],W[J],y[J];c=C;w=W;Y=y;for(m=1;;m++){Q(c)if(!g(0))R m-1;}}

518 bajtów, DFS z przycinaniem, O (2 n )

#define R return
#define Z(q)for(j=q;j<I;j++)
#define Q(q)memset(q,0,4*J);
#define V(Q)t=Q;if(!Y[t]){G-=Y[t]=1;b[B++]=t;}
#define F(q)if(S(x q j,y+j)){V((x q j)*I+y+j)}
int*c,*w,*Y,j,k,r,I,J,m;S(x,y){R x>=0&&x<I&&y>=0&&y<I;}D(l,H){int i,b[J],B,t,x,y,G;if(l==m)R 1;for(i=!l?0:w[l-1]+1;i<J;i++){if(!c[i]){c[i]=1;w[l]=i;x=i/I;y=i%I;G=H;Z(B=0){V(x*I+j)V(j*I+y)}Z(-I){F(+)F(-)}if(G>=m&&D(l+1,G))R 1;for(j=B;j--;)Y[b[j]]=0;c[i]=0;}}R 0;}f(s){I=s;J=I*I;int C[J],W[J],y[J];c=C;w=W;Y=y;for(m=1;;m++){Q(c)Q(Y)if(!D(0,J))R m-1;}}

577 bajtów, DFS iterujące białe i czarne królowe, O (?)

#define R return
#define U(V,r,q)S(V,r[i]/I q j,r[i]%I+j)
#define W(q)for(j=q;j<I;j++)
#define Z(r,q,t,v)for(i=0;i<r;i++){t[q[i]]=1;W(0)v[T(q[i]/I,j)]=v[T(j,q[i]%I)]=1;W(-I)U(v,q,+),U(v,q,-);};
#define P(K,L,M)memcpy(v,K,4*J);for(i=0;i<J;i++)if(!v[i]){L[M++]=i;if(g(E,N,!C))R 1;M--;};
int*w,*b,m,I,J;T(i,j){R i*I+j;}Q(int*q){memset(q,0,4*J);}S(V,x,y)int*V;{x>=0&&x<I&&y>=0&&y<I?V[T(x,y)]=1:0;}g(E,N,C){int i,j,v[J],X[J],Y[J];if(E==m&&N==m)R 1;Q(X);Q(Y);Z(E,w,X,Y)Z(N,b,Y,X)if(C){P(Y,b,N)}else{P(X,w,E)}R 0;}f(q){I=q,J=I*I;int W[J],B[J];w=W,b=B;for(m=1;;m++)if(!g(0,0,0))R m-1;}

Zasadniczo kod iteruje możliwości białej królowej i sprawdza, czy w takim razie można ją umieścić.

Tabela prędkości odniesienia (w sekundach):

+---+----------------------+---------------------+-----------------+--------+
| n |      DFS w & b       |        DFS w        |  DFS w/ pruning | Clingo |
+---+----------------------+---------------------+-----------------+--------+
| 3 |                 0.00 |                0.00 |            0.00 |   0.01 |
| 4 |                 0.00 |                0.00 |            0.00 |   0.02 |
| 5 |                 0.47 |                0.16 |            0.00 |   0.04 |
| 6 |                20.62 |                1.14 |            0.00 |   0.60 |
| 7 |              1125.07 |              397.88 |            0.63 |  18.14 |
| 8 |                      |                     |            1.28 | 979.35 |
| 9 |                      |                     |           23.13 |        |
+---+----------------------+---------------------+-----------------+--------+
Keyu Gan
źródło
2

Clingo , 90 bajtów

{q(1..n,1..n)}.a(X+(-I;0;I),Y+(0;I)):-q(X,Y),I=-n..n.:~K={q(X,Y)},{a(1..n,1..n)}n*n-K.[-K]

Próbny

$ clingo peaceable.lp -cn=6
clingo version 5.1.0
Reading from peaceable.lp
Solving...
Answer: 1

Optimization: 0
Answer: 2
q(6,1) a(7,1) a(7,2) a(8,1) a(8,3) a(9,1) a(9,4) a(10,1) a(10,5) a(11,1) a(11,6) a(12,1) a(6,1) a(6,2) a(6,3) a(6,4) a(6,5) a(6,6) a(5,1) a(5,2) a(4,1) a(4,3) a(3,1) a(3,4) a(2,1) a(2,5) a(1,1) a(1,6) a(0,1) a(7,0) a(8,-1) a(9,-2) a(10,-3) a(11,-4) a(12,-5) a(6,-4) a(6,-3) a(6,-2) a(6,-1) a(6,0) a(5,0) a(4,-1) a(0,7) a(1,-4) a(2,-3) a(3,-2) a(6,-5) a(6,7) a(0,-5) a(12,7)
Optimization: -1
Answer: 3
q(1,6) q(6,1) a(7,1) a(7,2) a(7,6) a(8,1) a(8,3) a(9,1) a(9,4) a(10,1) a(10,5) a(11,1) a(11,6) a(12,1) a(6,1) a(6,2) a(6,3) a(6,4) a(6,5) a(6,6) a(5,1) a(5,2) a(5,6) a(4,1) a(4,3) a(4,6) a(3,1) a(3,4) a(3,6) a(2,1) a(2,5) a(2,6) a(1,1) a(1,2) a(1,3) a(1,4) a(1,5) a(1,6) a(0,1) a(0,5) a(0,6) a(-1,4) a(-1,6) a(-2,3) a(-2,6) a(-3,2) a(-3,6) a(-4,1) a(-4,6) a(-5,6) a(7,0) a(8,-1) a(9,-2) a(10,-3) a(11,-4) a(12,-5) a(6,-4) a(6,-3) a(6,-2) a(6,-1) a(6,0) a(5,0) a(4,-1) a(0,7) a(1,7) a(2,7) a(-1,8) a(1,8) a(3,8) a(-2,9) a(1,9) a(-3,10) a(1,10) a(-4,11) a(1,11) a(-5,12) a(1,-4) a(1,0) a(2,-3) a(3,-2) a(6,-5) a(6,7) a(4,9) a(5,10) a(6,11) a(1,12) a(-5,0) a(0,-5) a(7,12) a(12,7)
Optimization: -2
Answer: 4
q(1,6) q(6,1) q(6,6) a(7,1) a(7,2) a(7,5) a(7,6) a(8,1) a(8,3) a(8,4) a(8,6) a(9,1) a(9,3) a(9,4) a(9,6) a(10,1) a(10,2) a(10,5) a(10,6) a(11,1) a(11,6) a(12,1) a(12,6) a(6,1) a(6,2) a(6,3) a(6,4) a(6,5) a(6,6) a(5,1) a(5,2) a(5,5) a(5,6) a(4,1) a(4,3) a(4,4) a(4,6) a(3,1) a(3,3) a(3,4) a(3,6) a(2,1) a(2,2) a(2,5) a(2,6) a(1,1) a(1,2) a(1,3) a(1,4) a(1,5) a(1,6) a(0,1) a(0,5) a(0,6) a(-1,4) a(-1,6) a(-2,3) a(-2,6) a(-3,2) a(-3,6) a(-4,1) a(-4,6) a(-5,6) a(7,0) a(8,-1) a(9,-2) a(10,-3) a(11,-4) a(12,-5) a(12,0) a(6,-4) a(6,-3) a(6,-2) a(6,-1) a(6,0) a(5,0) a(4,-1) a(0,7) a(1,7) a(2,7) a(5,7) a(-1,8) a(1,8) a(3,8) a(4,8) a(-2,9) a(1,9) a(3,9) a(-3,10) a(1,10) a(2,10) a(-4,11) a(1,11) a(-5,12) a(0,12) a(1,-4) a(1,0) a(2,-3) a(3,-2) a(6,-5) a(6,7) a(6,8) a(4,9) a(6,9) a(5,10) a(6,10) a(6,11) a(1,12) a(6,12) a(-5,0) a(0,-5) a(0,0) a(7,7) a(8,8) a(9,9) a(10,10) a(11,11) a(7,12) a(12,7) a(12,12)
Optimization: -3
Answer: 5
q(1,1) q(1,6) q(6,1) q(6,6) a(7,1) a(7,2) a(7,5) a(7,6) a(8,1) a(8,3) a(8,4) a(8,6) a(9,1) a(9,3) a(9,4) a(9,6) a(10,1) a(10,2) a(10,5) a(10,6) a(11,1) a(11,6) a(12,1) a(12,6) a(6,1) a(6,2) a(6,3) a(6,4) a(6,5) a(6,6) a(5,1) a(5,2) a(5,5) a(5,6) a(4,1) a(4,3) a(4,4) a(4,6) a(3,1) a(3,3) a(3,4) a(3,6) a(2,1) a(2,2) a(2,5) a(2,6) a(1,1) a(1,2) a(1,3) a(1,4) a(1,5) a(1,6) a(0,1) a(0,2) a(0,5) a(0,6) a(-1,1) a(-1,3) a(-1,4) a(-1,6) a(-2,1) a(-2,3) a(-2,4) a(-2,6) a(-3,1) a(-3,2) a(-3,5) a(-3,6) a(-4,1) a(-4,6) a(-5,1) a(-5,6) a(7,-5) a(7,0) a(8,-1) a(9,-2) a(10,-3) a(11,-4) a(12,-5) a(12,0) a(6,-4) a(6,-3) a(6,-2) a(6,-1) a(6,0) a(5,-3) a(5,0) a(4,-2) a(4,-1) a(3,-1) a(2,0) a(0,7) a(1,7) a(2,7) a(5,7) a(-1,8) a(1,8) a(3,8) a(4,8) a(-2,9) a(1,9) a(3,9) a(-3,10) a(1,10) a(2,10) a(-4,11) a(1,11) a(-5,7) a(-5,12) a(0,12) a(1,-5) a(1,-4) a(1,-3) a(1,-2) a(1,-1) a(1,0) a(2,-3) a(3,-2) a(6,-5) a(6,7) a(6,8) a(4,9) a(6,9) a(5,10) a(6,10) a(6,11) a(1,12) a(6,12) a(-5,-5) a(-5,0) a(-4,-4) a(-3,-3) a(-2,-2) a(-1,-1) a(0,-5) a(0,0) a(7,7) a(8,8) a(9,9) a(10,10) a(11,11) a(7,12) a(12,7) a(12,12)
Optimization: -4
Answer: 6
q(1,2) q(1,3) q(2,2) q(2,3) q(2,6) a(7,1) a(7,2) a(7,3) a(7,6) a(8,2) a(8,3) a(8,6) a(6,2) a(6,3) a(6,6) a(5,2) a(5,3) a(5,5) a(5,6) a(4,1) a(4,2) a(4,3) a(4,4) a(4,5) a(4,6) a(3,1) a(3,2) a(3,3) a(3,4) a(3,5) a(3,6) a(2,1) a(2,2) a(2,3) a(2,4) a(2,5) a(2,6) a(1,1) a(1,2) a(1,3) a(1,4) a(1,5) a(1,6) a(0,1) a(0,2) a(0,3) a(0,4) a(0,5) a(0,6) a(-1,1) a(-1,2) a(-1,3) a(-1,4) a(-1,5) a(-1,6) a(-2,2) a(-2,3) a(-2,5) a(-2,6) a(-3,1) a(-3,2) a(-3,3) a(-3,6) a(-4,2) a(-4,3) a(-4,6) a(-5,2) a(-5,3) a(7,-4) a(7,-3) a(7,-2) a(8,-4) a(8,-3) a(8,0) a(6,-3) a(6,-2) a(6,-1) a(5,-2) a(5,-1) a(5,0) a(4,-1) a(4,0) a(3,0) a(2,0) a(1,7) a(2,7) a(3,7) a(5,7) a(0,8) a(1,8) a(2,8) a(4,8) a(-2,7) a(-1,9) a(1,9) a(2,9) a(-3,7) a(-3,8) a(-2,10) a(2,10) a(-4,7) a(-4,8) a(-4,9) a(-3,11) a(-5,8) a(-5,9) a(-4,12) a(1,-4) a(1,-3) a(1,-2) a(1,-1) a(1,0) a(2,-4) a(2,-3) a(2,-2) a(2,-1) a(6,7) a(6,8) a(5,9) a(6,10) a(2,11) a(2,12) a(-5,-4) a(-5,-3) a(-4,-4) a(-4,-3) a(-4,-2) a(-4,0) a(-3,-3) a(-3,-2) a(-3,-1) a(-2,-2) a(-2,-1) a(-2,0) a(-1,-1) a(-1,0) a(0,0) a(7,7) a(7,8) a(8,8) a(7,9) a(8,9) a(7,11) a(8,12)
Optimization: -5
OPTIMUM FOUND

Models       : 6
  Optimum    : yes
Optimization : -5
Calls        : 1
Time         : 0.733s (Solving: 0.71s 1st Model: 0.00s Unsat: 0.71s)
CPU Time     : 0.730s
Anders Kaseorg
źródło
czy mógłbyś napisać małe wyjaśnienie?
Keyu Gan,
2

Python 2 | 325 284 217 bajtów

Wypróbuj online!

from itertools import*
N=input()
r=range(N*N)
for n in r:
 g=r
 for s in combinations(g,n):
    for p in s:g=filter(lambda q:all([abs(q%N-p%N)!=abs(q/N-p/N),q%N!=p%N,q/N!=p/N]),g)
    if len(g)>=n:break
    g=r
 else:exit(n-1)

Edycja: Zastąpiono krotki liczbami całkowitymi wg i innymi trywialnymi zmianami.

Edycja2: Bajty do 217 dzięki musicman523 i CalculatorFeline !

Jak to działa

Program dokonuje iteracji po wszystkich możliwych pozycjach nkrólowych i odfiltrowuje niepasujące punkty gspowodowane przez pozycję królowych. Jeśli pozostałe punkty są większe niż nwtedy, oznacza to, że narmie królowej mogą pozostać w spokoju. Jeśli dla następnej wartości nnie zostanie znaleziona sytuacja pokojowa, program zakończy działanie z kodem wyjścia:, n-1który jest odpowiedzią. Krótko mówiąc, jest to brutalna siła

Program można przyspieszyć, zmieniając dwa ostatnie wiersze na

for n in range(N**2):
    if not z(n,N):print n-1;break
dark32
źródło
2
Wskazówka: 1 spacja i 1 tab to różne poziomy wcięcia w Pythonie 2. Możesz także użyć from module import*do importowania wszystkiego z modułu i zapisywania bajtów.
CalculatorFeline
1
Tłumacz
języka
1

Haskell , 169 156 153 152 bajtów

k!(a:b)=k!b++[a:c|c<-(k-1)!b]
k!x=[x|k==0]
q&l|p<-q![[x,y,x-y,x+y]|x<-l,y<-l]=or[all and$zipWith(/=)<$>b<*>w|b<-p,w<-p]
g n=last$filter(&[1..n])[0..n*n]

Definiuje funkcję g, może być dodatkowo grywalna. Wypróbuj online! W przypadku TIO po skompilowaniu -O2zajmuje to około 36 sekund dla n = 4, a limit czasu dla n = 5 . Złożoność czasowa powinna wynosić O (n 2 4 n 2 ) .

Wyjaśnienie

Iterujemy ponad możliwymi wartościami liczby królowych ( q ). Dla każdego q generujemy wszystkie pary podzbiorów rozmiar- q z [1..n] 2 , jeden zestaw czarnych królowych ( b ) i jeden z białych królowych ( w ). Następnie każdy element b jest sprawdzany względem każdego elementu w, aby sprawdzić, czy mają one wspólny rząd, kolumnę, przekątną lub anty-przekątną. Dotyczy to również dwóch elementów o tej samej współrzędnej. Największa wartość q która dopuszcza konfigurację pokojową, jest wartość końcowa.

Pierwsze dwa wiersze programu określają funkcję !, która oblicza kpodsekwencje długości listy x. Implementacja odbywa się przez podstawową rekurencję: albo wybierz pierwszy element, który ma być w zestawie, albo nie, i wróć do ogona, zmniejszając w krazie potrzeby. Następnie pusta lista lub osiągnięty, sprawdź to k==0.

k!(a:b)=       -- ! on integer k and list with head a and tail b is
 k!b++         -- the concatenation of k!b and
 [a:c|         -- the list of lists a:c where
  c<-(k-1)!b]  -- c is drawn from (k-1)!b.
k!x=           -- If x doesn't have the form a:b (which means that it's empty),
 [x|           -- the result is a list containing x
  k==0]        -- but only if k==0.

Druga funkcja pomocnicza &pobiera liczbę q(liczbę królowych po każdej stronie) i listę l(współrzędne x planszy, używane również jako współrzędne y) i zwraca wartość logiczną wskazującą, czy istnieje konfiguracja pokojowa. Najpierw obliczamy plistę qpodsekwencji długości listy wartości [x,y,x-y,x+y], gdzie xi yzakres l. Reprezentują rząd, kolumnę, przekątną i anty-przekątną kwadratu (x,y)na planszy.

q&l               -- & on inputs q and l:
 |p<-             -- define p as
  q!              -- the q-subsequences of
  [[x,y,x-y,x+y]  -- the list of these 4-lists
   |x<-l,y<-l]    -- where x and y are drawn independently from l.

Następnie mamy wynik q&l. Zwracamy dwa krótsze sekwencje bi wod p, powiązać 4-list nich razem na wszystkie możliwe sposoby i sprawdzić, że zawsze różnią się we wszystkich 4 współrzędnych. Jeśli niektóre wybory bi wwynik prawdziwego wyniku, wrócimy True.

=or            -- Does the following list contain a True:
 [all and$     -- every list contains only truthy values
  zipWith(/=)  -- if we zip with inequality
  <$>b<*>w     -- all elements of b and w in all possible ways,
 |b<-p,w<-p]   -- where b and w are drawn independently from p.

Ostatni wiersz jest główną funkcją. Biorąc pod uwagę n, po prostu znajduje największą możliwą wartość, qdla której q&[1..n]jest to prawda.

g n=              -- g on input n is
 last$            -- the last of
 filter(&[1..n])  -- those values q for which q&[1..n] is true
 [0..n*n]         -- in this list.
Zgarb
źródło