Task: Peaceful chess queen armies


C++: #include <iostream>
#include <vector>

enum class Piece {
    empty,
    black,
    white
};

typedef std::pair<int, int> position;

bool isAttacking(const position &queen, const position &pos) {
    return queen.first == pos.first
        || queen.second == pos.second
        || abs(queen.first - pos.first) == abs(queen.second - pos.second);
}

bool place(const int m, const int n, std::vector<position> &pBlackQueens, std::vector<position> &pWhiteQueens) {
    if (m == 0) {
        return true;
    }
    bool placingBlack = true;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            auto pos = std::make_pair(i, j);
            for (auto queen : pBlackQueens) {
                if (queen == pos || !placingBlack && isAttacking(queen, pos)) {
                    goto inner;
                }
            }
            for (auto queen : pWhiteQueens) {
                if (queen == pos || placingBlack && isAttacking(queen, pos)) {
                    goto inner;
                }
            }
            if (placingBlack) {
                pBlackQueens.push_back(pos);
                placingBlack = false;
            } else {
                pWhiteQueens.push_back(pos);
                if (place(m - 1, n, pBlackQueens, pWhiteQueens)) {
                    return true;
                }
                pBlackQueens.pop_back();
                pWhiteQueens.pop_back();
                placingBlack = true;
            }

        inner: {}
        }
    }
    if (!placingBlack) {
        pBlackQueens.pop_back();
    }
    return false;
}

void printBoard(int n, const std::vector<position> &blackQueens, const std::vector<position> &whiteQueens) {
    std::vector<Piece> board(n * n);
    std::fill(board.begin(), board.end(), Piece::empty);

    for (auto &queen : blackQueens) {
        board[queen.first * n + queen.second] = Piece::black;
    }
    for (auto &queen : whiteQueens) {
        board[queen.first * n + queen.second] = Piece::white;
    }

    for (size_t i = 0; i < board.size(); ++i) {
        if (i != 0 && i % n == 0) {
            std::cout << '\n';
        }
        switch (board[i]) {
        case Piece::black:
            std::cout << "B ";
            break;
        case Piece::white:
            std::cout << "W ";
            break;
        case Piece::empty:
        default:
            int j = i / n;
            int k = i - j * n;
            if (j % 2 == k % 2) {
                std::cout << "x ";
            } else {
                std::cout << "* ";
            }
            break;
        }
    }

    std::cout << "\n\n";
}

int main() {
    std::vector<position> nms = {
        {2, 1}, {3, 1}, {3, 2}, {4, 1}, {4, 2}, {4, 3},
        {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5},
        {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 6},
        {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 7},
    };

    for (auto nm : nms) {
        std::cout << nm.second << " black and " << nm.second << " white queens on a " << nm.first << " x " << nm.first << " board:\n";
        std::vector<position> blackQueens, whiteQueens;
        if (place(nm.second, nm.first, blackQueens, whiteQueens)) {
            printBoard(nm.first, blackQueens, whiteQueens);
        } else {
            std::cout << "No solution exists.\n\n";
        }
    }

    return 0;
}


C#: using System;
using System.Collections.Generic;

namespace PeacefulChessQueenArmies {
    using Position = Tuple<int, int>;

    enum Piece {
        Empty,
        Black,
        White
    }

    class Program {
        static bool IsAttacking(Position queen, Position pos) {
            return queen.Item1 == pos.Item1
                || queen.Item2 == pos.Item2
                || Math.Abs(queen.Item1 - pos.Item1) == Math.Abs(queen.Item2 - pos.Item2);
        }

        static bool Place(int m, int n, List<Position> pBlackQueens, List<Position> pWhiteQueens) {
            if (m == 0) {
                return true;
            }
            bool placingBlack = true;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    var pos = new Position(i, j);
                    foreach (var queen in pBlackQueens) {
                        if (queen.Equals(pos) || !placingBlack && IsAttacking(queen, pos)) {
                            goto inner;
                        }
                    }
                    foreach (var queen in pWhiteQueens) {
                        if (queen.Equals(pos) || placingBlack && IsAttacking(queen, pos)) {
                            goto inner;
                        }
                    }
                    if (placingBlack) {
                        pBlackQueens.Add(pos);
                        placingBlack = false;
                    } else {
                        pWhiteQueens.Add(pos);
                        if (Place(m - 1, n, pBlackQueens, pWhiteQueens)) {
                            return true;
                        }
                        pBlackQueens.RemoveAt(pBlackQueens.Count - 1);
                        pWhiteQueens.RemoveAt(pWhiteQueens.Count - 1);
                        placingBlack = true;
                    }
                inner: { }
                }
            }
            if (!placingBlack) {
                pBlackQueens.RemoveAt(pBlackQueens.Count - 1);
            }
            return false;
        }

        static void PrintBoard(int n, List<Position> blackQueens, List<Position> whiteQueens) {
            var board = new Piece[n * n];

            foreach (var queen in blackQueens) {
                board[queen.Item1 * n + queen.Item2] = Piece.Black;
            }
            foreach (var queen in whiteQueens) {
                board[queen.Item1 * n + queen.Item2] = Piece.White;
            }

            for (int i = 0; i < board.Length; i++) {
                if (i != 0 && i % n == 0) {
                    Console.WriteLine();
                }
                switch (board[i]) {
                    case Piece.Black:
                        Console.Write("B ");
                        break;
                    case Piece.White:
                        Console.Write("W ");
                        break;
                    case Piece.Empty:
                        int j = i / n;
                        int k = i - j * n;
                        if (j % 2 == k % 2) {
                            Console.Write("  ");
                        } else {
                            Console.Write("# ");
                        }
                        break;
                }
            }

            Console.WriteLine("\n");
        }

        static void Main() {
            var nms = new int[,] {
                {2, 1}, {3, 1}, {3, 2}, {4, 1}, {4, 2}, {4, 3},
                {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5},
                {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 6},
                {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 7},
            };
            for (int i = 0; i < nms.GetLength(0); i++) {
                Console.WriteLine("{0} black and {0} white queens on a {1} x {1} board:", nms[i, 1], nms[i, 0]);
                List<Position> blackQueens = new List<Position>();
                List<Position> whiteQueens = new List<Position>();
                if (Place(nms[i, 1], nms[i, 0], blackQueens, whiteQueens)) {
                    PrintBoard(nms[i, 0], blackQueens, whiteQueens);
                } else {
                    Console.WriteLine("No solution exists.\n");
                }
            }
        }
    }
}