How many squares are guarded by chess queens?

6

1

Today marks the 15th anniversary of Garry Kasparov's defeat against Deep Blue. Speaking of chess...

Input is a string that represents an 8x8 chess board containing only empty squares (.) and queens (Q). Output the number of squares that any queen can move to the next move. Queens can move any number of squares vertically, horizontally or diagonally.

Write either a program or a function. Shortest code wins, but most inventive solution gets the most upvotes.

Examples

Input:

Q.......
........
.Q......
........
........
........
........
........

Output:

37

Input:

QQQQQQQQ
QQQQQQQQ
QQQQQQQQ
QQQQ.QQQ
QQQQQQQQ
QQQQQQQQ
QQQQQQQQ
QQQQQQQQ

Output:

1

user475

Posted 2011-02-10T22:39:47.140

Reputation:

1@Tim the correct output for the first test case is 36. I think you forgot to count the down-right diagonal from the second queen. – Peter Taylor – 2011-02-10T22:53:51.110

@Peter You're right, I missed that diagonal. That's what I get for trying to do a computer's job. – None – 2011-02-10T23:06:20.280

1I get 37 for the first test case – gnibbler – 2011-02-10T23:09:54.860

@gnibbler The upper-left queen reaches 7 squares in each of 3 directions. Since we don't count overlaps, the other queen reaches 5 squares in each of 3 directions. (37+35=36) – None – 2011-02-10T23:14:17.770

@Tim: you are forgetting about c7 (for a total of 37) – BlueRaja - Danny Pflughoeft – 2011-02-10T23:28:48.063

@BRDP: You're right! I'll stop trying to count them and get on with my solution now. @gnibbler You're right too :) – None – 2011-02-10T23:30:31.627

I thought this question would attract more answers – gnibbler – 2011-02-12T07:00:47.013

This is a duplicate of http://codegolf.com/dancing-queens. I guess it is okay to repost golf questions from other sources, but giving credit would seem appropriate.

– hallvabo – 2011-03-31T19:55:06.960

@hallvabo: First, the problems are different. The answer to my second example would be 8 in the problem you linked. Second, it would be entirely reasonable that the same problem was thought of by two different sources. – None – 2011-04-04T10:46:23.980

@Tim: it's possible. Both challenges could also have a common ancestry (say, a textbook task).
And the difference is trivial, my solution to Dancing Queens is almost identical to gnibbler's 125 byte solution here. Anyway, people who enjoyed this challenge might like to try Dancing Queen too :-)
– hallvabo – 2011-04-04T11:26:46.253

Answers

5

Python - 125 chars

import os
s=os.read(0,99)
print sum(any('*'<s[i]!='Q'in s[i::j].split()[0]for j in(-10,-9,-8,-1,1,8,9,10))for i in range(71))

gnibbler

Posted 2011-02-10T22:39:47.140

Reputation: 14 170

Seems not to count h1. Fill all squares except the bottom right corner and your script says 1. – None – 2011-02-10T23:37:47.467

1@Tim, brainfart, i thought i was counting an extra one for the newline at the end because i kept getting 37 for case 1 :) – gnibbler – 2011-02-10T23:45:41.810

7

APL, 40 characters

≢⍸a<∨/(⍳8 8)∘.{∨/⊃=/(⊢,+/,-/)¨⍺⍵}⍸a←'Q'=

⍸a←'Q'= transforms the matrix in a nested vector whose elements are the coordinates of the given queens.

(⊢,+/,-/) returns for every cell: the coordinates, their sum, their difference.

{∨/⊃=/(⊢,+/,-/)¨⍺ ⍵} returns 1 if cells ⍺ & ⍵ share one coordinate, the coordinates sum or the coordinates difference; that is gives 1 if a queen can move orizontally, vertically or diagonally from ⍺ to ⍵.

⍵∘.{∨/⊃=/(⊢,+/,-/)¨⍺⍵}⍳8 8 applies the previous function to each queen and each cell in the chessboard.

∨⌿ returns the boolean matrix of cell reachable from some queens ≢⍸a< counts the cell reachable by the queens and not already occupied by queens.

michele

Posted 2011-02-10T22:39:47.140

Reputation: 71

What language is this? – undergroundmonorail – 2017-10-27T06:54:46.077

Welcome to PPCG! – Martin Ender – 2017-10-27T07:23:37.327

5

APL, 37 chars

{≢t~⍨⍸∨/(=/∘|∨0∘∊)¨(⍳8 8)∘.-t←⍸'Q'=⍵}
  • 'Q'=⍵ gives boolean mask of queens
  • gives vector of coordinates (row, column) of queens
  • t← stores the result in var t
  • (⍳8 8)∘.- outer product: gives "distances" (∆row, ∆column) between all grid cells and queen cells
  • 0∘∊ checks if either ∆row or ∆column is 0
  • =/∘| checks if ∆row = +/- ∆column
  • (=/∘|∨0∘∊)¨ checks both conditions for all "distances"
  • ∨/ checks if at least one of those checks return true
  • gives vector of coordinates (row, column) of reachable cells
  • t~⍨ removes original queens' positions
  • count

Popov

Posted 2011-02-10T22:39:47.140

Reputation: 101

Welcome to PPCG! – Martin Ender – 2017-10-27T08:29:47.257

you can save a char by computing the abs value a little earlier - right after the outer product – ngn – 2017-10-27T12:22:31.493

3

APL, 50 chars

{≢(b~x)∩,(x←(,'Q'=⍵)/b←,⍳8 8)∘.+(⍳8)∘.×∘.,⍨1 0 ¯1}

In English:

  • ∘.,⍨1 0 ¯1: computes all the pairs composed by -1, 0 or 1, i.e.: (0 0)(0 1)(0 -1)(1 0) and so on;
  • (⍳8)∘.×∘.,⍨1 0 ¯1: multiply all the pairs computed by all the number from 1 to 8, obtaining all the possible offsets of movement of the queen;
  • (x←(,'Q'=⍵)/b←,⍳8 8): puts is x the coordinates of the given queens;
  • ∘.+: compute yet another outer sum, combining the position of the given queens with all the possible displacement offsets. This gives a multidimensional array of coordinate pairs of all the possible place where each of the queens might end up, including outside the board (whose valid coordinate pairs is in b)
  • (b~x)∩,: removes from the list b all the coordinates taken by the queens in the given (x) and intersects it with flattened array of pairs of all the possible positions of the queens
  • : count the remaining pairs

Try online sample 1.

Try online sample 2

lstefano

Posted 2011-02-10T22:39:47.140

Reputation: 850

1The array literal at the end of your code could be 2-⍳3 if index origin is 1, 1-⍳3 if it's 0. – Zacharý – 2017-07-31T22:48:48.363

3

Java Solution

public class NewQueenProblem {  
        public static int countMoves(String input){
            int moves=0;
            class Board{
                char data;
                boolean visited;
            }
            Board[][] board=new Board[8][8];
            int x=0;
            for (int i=0; i< 64; i++){
                board[x%8][i%8] = new Board();
                board[x%8][i%8].data=input.charAt(i);
                if ((i+1)%8==0)
                    x++;
            }
            for (int i=0; i< 8; i++){
                for (int j=0; j< 8; j++){
                    if (board[i][j].data == 'Q'){
                        for (int row=0; row<8; row++)
                            if (board[i][row].data != 'Q' && !board[i][row].visited)
                                { moves++; board[i][row].visited=true;}
                        for (int col=0; col<8; col++)
                            if (board[col][j].data != 'Q' && !board[col][j].visited)
                                { moves++; board[col][j].visited=true;}
                        int posX=i, posY=j;
                        while (posX < 8 && posY < 8){
                            if (board[posX][posY].data != 'Q' && !board[posX][posY].visited)
                            { moves++; board[posX][posY].visited=true;}
                            posX++; posY++;
                        }
                        posX=i; posY=j;
                        while (posX > 0 && posY > 0){
                            if (board[posX][posY].data != 'Q' && !board[posX][posY].visited)
                            { moves++; board[posX][posY].visited=true;}
                            posX--; posY--;
                        }
                        posX=i; posY=j;
                        while (posX > 0 && posY < 8){
                            if (board[posX][posY].data != 'Q' && !board[posX][posY].visited)
                            { moves++; board[posX][posY].visited=true;}
                            posX--; posY++;
                        }
                        posX=i; posY=j;
                        while (posX < 8 && posY > 0){
                            if (board[posX][posY].data != 'Q' && !board[posX][posY].visited)
                            { moves++; board[posX][posY].visited=true;}
                            posX++; posY--;
                        }                   
                    }
                }
            }
            return moves;
        }
public static void main(String[] args) {
        int moves = countMoves("Q................Q..............................................");
        //int moves = countMoves("QQQQQQQQQQQQQQQQQQQQQQQQQQQQ.QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
        System.out.println(moves);
    }
}

Aman ZeeK Verma

Posted 2011-02-10T22:39:47.140

Reputation: 609

1http://www.ideone.com/KFxxd oops that's ~1800 characters – Aman ZeeK Verma – 2011-02-11T01:44:29.493

5Please golf this. – SuperJedi224 – 2015-11-24T15:57:22.597

0

JavaScript 140 bytes

f=a=>a.split`
`.map((r,y,G)=>[...r].map((c,x)=>A+=c<"Q"&&G.some((R,Y)=>[...R].some((C,X)=>C>"."&&((d=X-x)*(D=Y-y)==0||d**2==D**2)))),A=0)&&A

console.log(f(`Q.......
........
.Q......
........
........
........
........
........`)==37)

console.log(f(`QQQQQQQQ
QQQQQQQQ
QQQQQQQQ
QQQQ.QQQ
QQQQQQQQ
QQQQQQQQ
QQQQQQQQ
QQQQQQQQ`)==1)

DanielIndie

Posted 2011-02-10T22:39:47.140

Reputation: 1 220

0

Perl 5, 172 + 3 (-pF) bytes

push@a,[@F]}{for$i(0..7){O:for$j(0..7){for$x(-1..1){for$y(-1..1){if($x|$y){$r=$i;$c=$j;$a[$i][$j]ne Q&&$a[$r][$c]eq Q&&++$\&&next O while(($r+=$x)^7)<8&&(($c+=$y)^7)<8}}}}}

Try it online!

There's got to be a better way to do it, but this at least works.

Xcali

Posted 2011-02-10T22:39:47.140

Reputation: 7 671