1
0
Fork 0
mirror of https://gitlab.com/mfocko/CodeWars.git synced 2024-11-21 16:13:47 +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:
Matej Focko 2022-08-11 19:50:35 +02:00
parent 851b2cc0bb
commit fd3b272a35
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 143 additions and 1 deletions

View 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;
}

View file

@ -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