mirror of
https://gitlab.com/mfocko/CodeWars.git
synced 2024-12-22 17:41:24 +01:00
4kyu: add „Shortest Knight Path“
• also move ISBN10 validation to correct language section Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
851b2cc0bb
commit
fd3b272a35
2 changed files with 143 additions and 1 deletions
141
4kyu/shortest_knight_path/solution.cpp
Normal file
141
4kyu/shortest_knight_path/solution.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include <cassert>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
int convert_column(char x) { return x - 'a'; }
|
||||
int convert_row(char y) { return y - '1'; }
|
||||
|
||||
template <typename T> bool in_range(const T &x, const T &min, const T &max) {
|
||||
return min <= x && x < max;
|
||||
}
|
||||
|
||||
template <typename T> using table_t = std::vector<std::vector<T>>;
|
||||
|
||||
static const std::vector<std::pair<int, int>> dpos{
|
||||
{-2, 1}, {-2, -1}, {-1, 2}, {-1, -2}, {1, 2}, {1, -2}, {2, 1}, {2, -1}};
|
||||
static const int dpos_size = static_cast<int>(dpos.size());
|
||||
|
||||
class position_t;
|
||||
std::ostream &operator<<(std::ostream &stream, const position_t &pos);
|
||||
|
||||
class position_t {
|
||||
int _x, _y;
|
||||
|
||||
public:
|
||||
position_t(int x, int y) : _x(x), _y(y) {}
|
||||
position_t(const std::pair<int, int> &coords)
|
||||
: _x(coords.first), _y(coords.second) {}
|
||||
position_t(const std::string &position)
|
||||
: _x(convert_column(position[0])), _y(convert_row(position[1])) {}
|
||||
|
||||
int x() const { return _x; }
|
||||
int y() const { return _y; }
|
||||
bool in_bounds() const { return in_range(_x, 0, 8) && in_range(_y, 0, 8); }
|
||||
|
||||
template <typename T> T &in(table_t<T> &table) const { return table[_y][_x]; }
|
||||
|
||||
bool operator==(const position_t &other) const {
|
||||
return _x == other._x && _y == other._y;
|
||||
}
|
||||
bool operator!=(const position_t &other) const {
|
||||
return _x != other._x || _y != other._y;
|
||||
}
|
||||
position_t operator+(const position_t &other) const {
|
||||
return {_x + other._x, _y + other._y};
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const position_t &pos) {
|
||||
stream << static_cast<char>('a' + pos.x())
|
||||
<< static_cast<char>('1' + pos.y());
|
||||
return stream;
|
||||
}
|
||||
|
||||
class adjacent_iterator {
|
||||
const position_t pos;
|
||||
int i;
|
||||
|
||||
position_t position() const { return pos + position_t(dpos[i]); }
|
||||
|
||||
adjacent_iterator &next() {
|
||||
do {
|
||||
i++;
|
||||
} while (i < dpos_size && !position().in_bounds());
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
adjacent_iterator(position_t pos) : pos(pos), i(-1) { next(); }
|
||||
adjacent_iterator(position_t pos, int i) : pos(pos), i(i) {}
|
||||
|
||||
bool operator!=(const adjacent_iterator &other) const {
|
||||
return pos != other.pos || i != other.i;
|
||||
}
|
||||
adjacent_iterator &operator++() { return next(); }
|
||||
position_t operator*() const { return position(); }
|
||||
};
|
||||
|
||||
class adjacent {
|
||||
const position_t &pos;
|
||||
|
||||
public:
|
||||
adjacent(const position_t &pos) : pos(pos) {}
|
||||
|
||||
adjacent_iterator begin() const { return {pos}; }
|
||||
adjacent_iterator end() const { return {pos, dpos_size}; }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int knight(std::string start, std::string finish) {
|
||||
position_t src(start);
|
||||
position_t dst(finish);
|
||||
|
||||
// construct table
|
||||
table_t<int> distances(8, std::vector<int>(8, -1));
|
||||
src.in(distances) = 0;
|
||||
|
||||
// run BFS and break once ‹finish› is found
|
||||
std::deque<position_t> queue{src};
|
||||
while (!queue.empty()) {
|
||||
position_t pos = queue.front();
|
||||
queue.pop_front();
|
||||
|
||||
int current_distance = pos.in(distances);
|
||||
for (const auto &next_pos : adjacent(pos)) {
|
||||
next_pos.in(distances) = current_distance + 1;
|
||||
queue.push_back(next_pos);
|
||||
|
||||
if (next_pos == dst) {
|
||||
// We have just set distance to the seeked position
|
||||
queue.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the distance to ‹finish›
|
||||
return dst.in(distances);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// position_t p("b8");
|
||||
// std::cout << "Constructed from string: " << p << "\n";
|
||||
|
||||
// std::cout << "===adjacent===\n";
|
||||
// for (auto pos : adjacent(p)) {
|
||||
// std::cout << pos << "\n";
|
||||
// }
|
||||
|
||||
assert(knight("a1", "c1") == 2);
|
||||
assert(knight("a1", "f1") == 3);
|
||||
assert(knight("a1", "f3") == 3);
|
||||
assert(knight("a1", "f4") == 4);
|
||||
assert(knight("a1", "f7") == 5);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -40,6 +40,7 @@
|
|||
- [Matrix Determinant](https://www.codewars.com/kata/52a382ee44408cea2500074c) - [solution](4kyu/matrix_determinant)
|
||||
- [Infix to Postfix Converter](https://www.codewars.com/kata/52e864d1ffb6ac25db00017f) - [solution](4kyu/infix_to_postfix_converter)
|
||||
- [Range Extraction](https://www.codewars.com/kata/51ba717bb08c1cd60f00002f) - [solution](4kyu/range_extraction)
|
||||
- [Shortest Knight Path](https://www.codewars.com/kata/549ee8b47111a81214000941) - [solution](4kyu/shortest_knight_path)
|
||||
|
||||
### JS
|
||||
|
||||
|
@ -87,6 +88,7 @@
|
|||
|
||||
- [int32 to IPv4](https://www.codewars.com/kata/52e88b39ffb6ac53a400022e) - [solution](5kyu/i32_to_ipv4)
|
||||
- [Convert A Hex String To RGB](https://www.codewars.com/kata/5282b48bb70058e4c4000fa7) - [solution](5kyu/convert_a_hex_string_to_rgb)
|
||||
- [ISBN-10 Validation](https://www.codewars.com/kata/51fc12de24a9d8cb0e000001) - [solution](5kyu/isbn10_validation)
|
||||
|
||||
### C++
|
||||
|
||||
|
@ -94,7 +96,6 @@
|
|||
- [Greed is Good](https://www.codewars.com/kata/5270d0d18625160ada0000e4) - [solution](5kyu/greed_is_good)
|
||||
- [Snakes and Ladders](https://www.codewars.com/kata/587136ba2eefcb92a9000027) - [solution](5kyu/snakes_and_ladders)
|
||||
- [The Clockwise Spiral](https://www.codewars.com/kata/536a155256eb459b8700077e) - [solution](5kyu/the_clockwise_spiral)
|
||||
- [ISBN-10 Validation](https://www.codewars.com/kata/51fc12de24a9d8cb0e000001) - [solution](5kyu/isbn10_validation)
|
||||
|
||||
### Python
|
||||
|
||||
|
|
Loading…
Reference in a new issue