this uses c++17 fold expressions to iterate over all the given arrays at the same time.
#include <vector> #include <iostream> #include <algorithm> constexpr auto iterateVectors = [](auto...vectors) { constexpr auto getSmallestVector = [](auto...vectors) { size_t end{ reinterpret_cast<size_t>(std::numeric_limits<size_t>::max) }; ((end = std::min(vectors.size(), end)), ...); return end; }; constexpr auto writeRow = [](size_t position, auto...vectors) -> void { const auto rowLength{ sizeof...(vectors) }; size_t i{ 0 }; ((std::cerr << vectors[position] << (++i < rowLength ? ':' : '\n')), ...); }; const size_t iterateFor{ getSmallestVector(vectors...) }; for (size_t i{ 0 }; i < iterateFor; i++) writeRow(i, vectors...); };
- #include <vector>
#include <utility>- #include <iostream>
template <class T, class U>void iterateTwoVectors(std::vector<T> A, std::vector<U> B)- #include <algorithm>
- constexpr auto iterateVectors = [](auto...vectors)
- {
- constexpr auto getSmallestVector = [](auto...vectors)
- {
- size_t end{ reinterpret_cast<size_t>(std::numeric_limits<size_t>::max) };
- ((end = std::min(vectors.size(), end)), ...);
- return end;
- };
- constexpr auto writeRow = [](size_t position, auto...vectors) -> void
- {
- const auto rowLength{ sizeof...(vectors) };
- size_t i{ 0 };
- ((std::cerr << vectors[position] << (++i < rowLength ? ':' : '\n')), ...);
- };
for (auto [a,b] = std::pair{A.begin(), B.begin()}; a != A.end() && b != B.end(); a++, b++){std::cout << *a << ":" << *b << "\n";}}- const size_t iterateFor{ getSmallestVector(vectors...) };
- for (size_t i{ 0 }; i < iterateFor; i++)
- writeRow(i, vectors...);
- };
// TODO: Replace examples and use TDD by writing your own tests Describe(iterating) { It(should_iterate_both) { std::vector<int> a{1, 2, 3}; std::vector<char> b{'a', 'b', 'c'}; std::vector<char> c{'a', 'b', 'c', 'd', 'e'}; iterateVectors(a, b, c); } };
- // TODO: Replace examples and use TDD by writing your own tests
- Describe(iterating)
- {
- It(should_iterate_both)
- {
iterateTwoVectors<int, char>({1, 'a', 3}, {'a', 'b'});- std::vector<int> a{1, 2, 3};
- std::vector<char> b{'a', 'b', 'c'};
- std::vector<char> c{'a', 'b', 'c', 'd', 'e'};
- iterateVectors(a, b, c);
- }
- };
given a board of NxN, if it's possible for a chess knight starting at position [0,0] to reach all the squares once only, the function should return true , otherwise the function should return false
In this implementation, there is an interface ChessPiece which we can implement to add the rules for all the chess pieces.
we recursivly check valid moves using a unique set to store the Squares we have already visited to prevent infinite recursion.
class Knight : public ChessPiece { std::vector<Square> possibleDirections{ {2, 1}, {2, -1}, {-2, 1}, {-2, -1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}, }; public: Knight(int boardSize) : ChessPiece(boardSize) { } virtual ~Knight() = default; bool positionInBounds(const Square& position) { return position.first > -1 && position.first < boardSize() && position.second > -1 && position.second < boardSize(); } // Inherited via ChessPiece virtual std::vector<Square> validMovesFromPosition(const Square& position) override { std::vector<Square> validDirections; for (auto direction : possibleDirections) { const Square possibleNewPos{position + direction}; if (positionInBounds(possibleNewPos)) validDirections.emplace_back(possibleNewPos); } return validDirections; } }; void traverseBoard(const std::unique_ptr<ChessPiece>& piece, const Square& currentPosition, std::set<Square>& visitedSquares) { const auto validPositions{piece->validMovesFromPosition(currentPosition)}; if (validPositions.size() == 0) return; std::vector<Square> unattemptedMoves; for (auto possibleMove : validPositions) { const auto result{visitedSquares.insert(possibleMove)}; if (result.second) unattemptedMoves.emplace_back(possibleMove); } for (auto unattemptedMove : unattemptedMoves) traverseBoard(piece, unattemptedMove, visitedSquares); } template<class C> bool attemptBoard(int width, Square startingPosition) { if (width < 1) return false; if (width == 1) return true; const std::unique_ptr<ChessPiece> piece{std::make_unique<C>(width)}; std::set<std::pair<int, int>> visitedSquares; traverseBoard(piece, startingPosition, visitedSquares); return visitedSquares.size() == static_cast<std::set<Square>::size_type>(width * width); } bool KnightTour(int n) { return attemptBoard<Knight>(n, {0, 0}); }
bool KnightTour(int n){- class Knight : public ChessPiece
- {
- std::vector<Square> possibleDirections{
- {2, 1},
- {2, -1},
- {-2, 1},
- {-2, -1},
- {1, 2},
- {-1, 2},
- {1, -2},
- {-1, -2},
- };
- public:
- Knight(int boardSize) : ChessPiece(boardSize)
- {
- }
- virtual ~Knight() = default;
- bool positionInBounds(const Square& position)
- {
- return position.first > -1 && position.first < boardSize()
- && position.second > -1 && position.second < boardSize();
- }
- // Inherited via ChessPiece
- virtual std::vector<Square> validMovesFromPosition(const Square& position) override
- {
- std::vector<Square> validDirections;
- for (auto direction : possibleDirections)
- {
- const Square possibleNewPos{position + direction};
- if (positionInBounds(possibleNewPos))
- validDirections.emplace_back(possibleNewPos);
- }
- return validDirections;
- }
- };
- void traverseBoard(const std::unique_ptr<ChessPiece>& piece, const Square& currentPosition, std::set<Square>& visitedSquares)
- {
- const auto validPositions{piece->validMovesFromPosition(currentPosition)};
- if (validPositions.size() == 0)
- return;
- std::vector<Square> unattemptedMoves;
- for (auto possibleMove : validPositions)
- {
- const auto result{visitedSquares.insert(possibleMove)};
- if (result.second)
- unattemptedMoves.emplace_back(possibleMove);
- }
- for (auto unattemptedMove : unattemptedMoves)
- traverseBoard(piece, unattemptedMove, visitedSquares);
- }
- template<class C>
- bool attemptBoard(int width, Square startingPosition)
- {
- if (width < 1)
- return false;
- if (width == 1)
- return true;
- const std::unique_ptr<ChessPiece> piece{std::make_unique<C>(width)};
- std::set<std::pair<int, int>> visitedSquares;
- traverseBoard(piece, startingPosition, visitedSquares);
- return visitedSquares.size() == static_cast<std::set<Square>::size_type>(width * width);
- }
- bool KnightTour(int n)
- {
- return attemptBoard<Knight>(n, {0, 0});
- }