Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tasks/cow/cow_string.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once

class CowString {
};
};
46 changes: 46 additions & 0 deletions tasks/robot/checkers_topology.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,47 @@
#include "checkers_topology.h"
CheckersTopology::CheckersTopology(const std::vector<std::vector<bool>>& field) : Topology(field) {
}
void CheckersTopology::Dfs(const Point& point, std::unordered_set<Point>& visited) const {
if (visited.contains(point)) {
return;
}
visited.insert(point);

for (int dx = -1; dx <= 1; dx += 2) {
for (int dy = -1; dy <= 1; dy += 2) {
int ix = static_cast<int>(point.x);
int iy = static_cast<int>(point.y);
if (!IsInField(ix + dx, iy + dy)) {
continue;
}
Point cur_point = MovedPoint(point, dx, dy);
ix = static_cast<int>(cur_point.x);
iy = static_cast<int>(cur_point.y);
if (IsAvailable(cur_point)) {
continue;
}
if (!IsInField(ix + dx, iy + dy) || !IsAvailable(MovedPoint(cur_point, dx, dy))) {
continue;
}
Dfs(MovedPoint(cur_point, dx, dy), visited);
}
}
}
std::vector<Point> CheckersTopology::GetAllNeighbours(const Point& point) const {
std::unordered_set<Point> visited;
int ix = static_cast<int>(point.x);
int iy = static_cast<int>(point.y);

Dfs(point, visited);
for (int dx = -1; dx <= 1; dx += 2) {
for (int dy = -1; dy <= 1; dy += 2) {
if (!IsInField(ix + dx, iy + dy)) {
continue;
}
visited.insert(MovedPoint(point, dx, dy));
}
}
visited.erase(point);

return std::vector<Point>(visited.begin(), visited.end());
}
11 changes: 10 additions & 1 deletion tasks/robot/checkers_topology.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#pragma once

#include "topology.h"
#include <unordered_set>

class CheckersTopology : public Topology {};
class CheckersTopology : public Topology {
public:
explicit CheckersTopology(const std::vector<std::vector<bool>>& field);

std::vector<Point> GetAllNeighbours(const Point& point) const override;

private:
void Dfs(const Point& point, std::unordered_set<Point>& visited) const;
};
20 changes: 20 additions & 0 deletions tasks/robot/knight_topology.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
#include "knight_topology.h"
KnightTopology::KnightTopology(const std::vector<std::vector<bool>>& field) : Topology(field) {
}
std::vector<Point> KnightTopology::GetAllNeighbours(const Point& point) const {
std::vector<Point> result;
int ix = static_cast<int>(point.x);
int iy = static_cast<int>(point.y);

for (int dx = -2; dx <= 2; dx++) {
for (int dy = -2; dy <= 2; dy++) {
if (abs(dx * dy) != 2) {
continue;
}
if (!IsInField(ix + dx, iy + dy)) {
continue;
}
result.emplace_back(MovedPoint(point, dx, dy));
}
}
return result;
}
7 changes: 6 additions & 1 deletion tasks/robot/knight_topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

#include "topology.h"

class KnightTopology : public Topology {};
class KnightTopology : public Topology {
public:
explicit KnightTopology(const std::vector<std::vector<bool>>& field);

std::vector<Point> GetAllNeighbours(const Point& point) const override;
};
25 changes: 25 additions & 0 deletions tasks/robot/overflow_topology.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
#include "overflow_topology.h"
OverflowTopology::OverflowTopology(const std::vector<std::vector<bool>>& field) : Topology(field) {
}
std::vector<Point> OverflowTopology::GetAllNeighbours(const Point& point) const {
std::vector<Point> result;
int ix = static_cast<int>(point.x);
int iy = static_cast<int>(point.y);

for (auto [dx, dy] : dd_) {
Point cur_point(point);
if (ix + dx < 0) {
cur_point.x = GetFieldWidth() - 1u;
} else if (ix + dx >= GetFieldWidth()) {
cur_point.x = 0u;
}

if (iy + dy < 0) {
cur_point.y = GetFieldHigh() - 1u;
} else if (iy + dy >= GetFieldHigh()) {
cur_point.y = 0u;
}
result.emplace_back(cur_point);
}

return result;
}
10 changes: 9 additions & 1 deletion tasks/robot/overflow_topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@

#include "topology.h"

class OverflowTopology : public Topology {};
class OverflowTopology : public Topology {
public:
explicit OverflowTopology(const std::vector<std::vector<bool>>& field);

std::vector<Point> GetAllNeighbours(const Point& point) const override;

private:
const int dd_[4][2] = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}};
};
16 changes: 16 additions & 0 deletions tasks/robot/planar_topology.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
#include "planar_topology.h"
PlanarTopology::PlanarTopology(const std::vector<std::vector<bool>>& field) : Topology(field) {
}
std::vector<Point> PlanarTopology::GetAllNeighbours(const Point& point) const {
std::vector<Point> result;
int ix = static_cast<int>(point.x);
int iy = static_cast<int>(point.y);

for (auto [dx, dy] : dd_) {
if (!IsInField(ix + dx, iy + dy)) {
continue;
}
result.emplace_back(MovedPoint(point, dx, dy));
}

return result;
}
10 changes: 9 additions & 1 deletion tasks/robot/planar_topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@

#include "topology.h"

class PlanarTopology : public Topology {};
class PlanarTopology : public Topology {
public:
explicit PlanarTopology(const std::vector<std::vector<bool>>& field);

std::vector<Point> GetAllNeighbours(const Point& point) const override;

private:
const int dd_[4][2] = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}};
};
12 changes: 12 additions & 0 deletions tasks/robot/point.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
#pragma once

#include <cstddef>
#include <functional>

struct Point {
size_t x = 0;
size_t y = 0;

bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
};

template <>
struct std::hash<Point> {
std::size_t operator()(const Point& point) const {
return (point.x + point.y * 132487) % 23489371;
}
};
34 changes: 34 additions & 0 deletions tasks/robot/robot.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
#include <queue>
#include "robot.h"

namespace robot {

Path FindPath(World& world) {
Path result;
Point cur_point = world.GetStart();
Point end_point = world.GetEnd();

result.emplace_back(cur_point);

while (cur_point != end_point) {
Point best_next = cur_point;
Topology::Distance min_dist(0);
for (const auto& [next, dist_to_end] : world.Lookup()) {
if (dist_to_end == Topology::UNREACHABLE) {
continue;
}
if (best_next == cur_point || dist_to_end < min_dist) {
best_next = next;
min_dist = dist_to_end;
}
}
if (cur_point == best_next) {
result.clear();
break;
}
cur_point = best_next;
world.Move(cur_point);
result.emplace_back(cur_point);
}
return result;
}
} // namespace robot
2 changes: 1 addition & 1 deletion tasks/robot/robot.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ using Path = std::vector<Point>;

Path FindPath(World& world);

}
} // namespace robot
55 changes: 55 additions & 0 deletions tasks/robot/topology.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
#include <queue>
#include "topology.h"
Field::Field(const std::vector<std::vector<bool>>& field) : field_(field) {
}
bool Field::IsAvailable(const Point& point) const {
return !field_[point.y][point.x];
}
size_t Field::GetFieldWidth() const {
return field_.empty() ? 0 : field_[0].size();
}
size_t Field::GetFieldHigh() const {
return field_.size();
}
bool Field::IsInField(int x, int y) const {
return x >= 0 && x < GetFieldWidth() && y >= 0 && y < GetFieldHigh();
}
std::vector<Point> Topology::GetNeighbours(const Point& point) const {
std::vector<Point> result;
for (const Point& next : GetAllNeighbours(point)) {
if (IsAvailable(next)) {
result.emplace_back(next);
}
}
return result;
}
Topology::Distance Topology::MeasureDistance(const Point& from, const Point& to) const {
std::unordered_map<Point, Distance> dist;

std::queue<Point> q;
q.push(from);
dist[from] = 0;
while (!q.empty()) {
Point cur_point = q.front();
q.pop();
if (cur_point == to) {
return dist[cur_point];
}
for (const Point& next : GetNeighbours(cur_point)) {
if (dist.contains(next)) {
continue;
}
dist[next] = dist[cur_point] + 1;
q.push(next);
}
}
return UNREACHABLE;
}
Topology::Topology(const std::vector<std::vector<bool>>& field) : Field(field) {
}
Point Topology::MovedPoint(const Point& point, int dx, int dy) const {
return Point{static_cast<size_t>(static_cast<int>(point.x) + dx),
static_cast<size_t>(static_cast<int>(point.y) + dy)};
}
std::vector<Point> Topology::GetAllNeighbours(const Point& point) const {
return std::vector<Point>();
}
26 changes: 23 additions & 3 deletions tasks/robot/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,32 @@

#include <vector>

class Topology {
class Field {
protected:
explicit Field(const std::vector<std::vector<bool>>& field);

bool IsAvailable(const Point& point) const;

size_t GetFieldWidth() const;
size_t GetFieldHigh() const;

bool IsInField(int x, int y) const;

std::vector<std::vector<bool>> field_;
};

class Topology : public Field {
public:
using Distance = ssize_t;

explicit Topology(const std::vector<std::vector<bool>>& field);

std::vector<Point> GetNeighbours(const Point& point) const;
Distance MeasureDistance(const Point& from, const Point& to) const;

static const Distance UNREACHABLE = -1;
};
Point MovedPoint(const Point& point, int dx, int dy) const;

virtual std::vector<Point> GetAllNeighbours(const Point& point) const;

inline static const Distance UNREACHABLE = -1;
};
24 changes: 24 additions & 0 deletions tasks/robot/world.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
#include "world.h"
World::World(const Topology& topology, Point start, Point end) : start_(start), end_(end), topology_(topology) {
}
std::unordered_map<Point, Topology::Distance> World::Lookup() const {
std::unordered_map<Point, Topology::Distance> result;
for (const Point& next : topology_.GetNeighbours(current_point_)) {
result[next] = topology_.MeasureDistance(next, end_);
}
return result;
}
const Point& World::GetStart() const {
return start_;
}
const Point& World::GetEnd() const {
return end_;
}
const Point& World::GetCurrentPosition() const {
return current_point_;
}
void World::Move(const Point& to) {
if (topology_.MeasureDistance(current_point_, to) != 1) {
throw IllegalMoveException();
}
current_point_ = to;
}
9 changes: 8 additions & 1 deletion tasks/robot/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ class World {
const Point& GetCurrentPosition() const;

void Move(const Point& to);
};

private:
Point start_;
Point end_;

Point current_point_;
const Topology& topology_;
};