From 5827c13df214ece32830e398414fefe6628124cb Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 18 Dec 2019 22:14:59 +0100 Subject: [PATCH] HW4: done --- chess_paths/chess_paths.c | 12 +-- roadmap/Makefile | 2 +- roadmap/roadmap.cpp | 169 +++++++++++++++++++++++++++++++------- roadmap/tests/test2.cpp | 2 +- 4 files changed, 147 insertions(+), 38 deletions(-) diff --git a/chess_paths/chess_paths.c b/chess_paths/chess_paths.c index c5ff568..c077241 100644 --- a/chess_paths/chess_paths.c +++ b/chess_paths/chess_paths.c @@ -217,12 +217,12 @@ void knight_positions(struct search_status* s, struct piece_position* p) { if (row >= 1 && col >= 2) consider(s, col - 2, row - 1); if (row >= 2 && col >= 1) consider(s, col - 1, row - 2); - if (row >= 2 && col <= cs - 1) consider(s, col + 1, row - 2); - if (row >= 1 && col <= cs - 2) consider(s, col + 2, row - 1); - if (row <= rs - 1 && col <= cs - 2) consider(s, col + 2, row + 1); - if (row <= rs - 2 && col <= cs - 1) consider(s, col + 1, row + 2); - if (row <= rs - 2 && col >= 1) consider(s, col - 1, row + 2); - if (row <= rs - 1 && col >= 2) consider(s, col - 2, row + 1); + if (row >= 2 && col + 1 <= cs) consider(s, col + 1, row - 2); + if (row >= 1 && col + 2 <= cs) consider(s, col + 2, row - 1); + if (row + 1 <= rs && col + 2 <= cs) consider(s, col + 2, row + 1); + if (row + 2 <= rs && col + 1 <= cs) consider(s, col + 1, row + 2); + if (row + 2 <= rs && col >= 1) consider(s, col - 1, row + 2); + if (row + 1 <= rs && col >= 2) consider(s, col - 2, row + 1); } void bishop_positions(struct search_status* s, struct piece_position* p) { diff --git a/roadmap/Makefile b/roadmap/Makefile index 75d359f..d2d9b5b 100644 --- a/roadmap/Makefile +++ b/roadmap/Makefile @@ -1,6 +1,6 @@ OBJECTS = roadmap.o CFLAGS=-Wall -g -CXXFLAGS=-Wall -g +CXXFLAGS=-Wall -g -std=c++11 SHELL=/bin/bash TIMEOUT=8 diff --git a/roadmap/roadmap.cpp b/roadmap/roadmap.cpp index 3996e8d..ab46585 100644 --- a/roadmap/roadmap.cpp +++ b/roadmap/roadmap.cpp @@ -1,44 +1,153 @@ +// vim: set ts=4 sw=4 et tw=80: + #include "roadmap.h" +#include #include #include +#include +#include -using std::map; -using std::set; +using namespace std; class ConcreteRoadMap : public AbstractRoadMap { -private: - int cities; + private: + map< string, set > adj; - map< string, set > adj; + /* + * Adds in the map for key city1 a new set with city2 inside if there is + * no prior set, otherwise it appends city2 into the existing set + */ + void addPair(const string& city1, const string& city2) { + this->adj[city1].insert(city2); + } - /* - * Adds in the map for key city1 a new set with city2 inside if there is no - * prior set, otherwise it appends city2 into the existing set - */ - void addPair(const string& city1, const string& city2) { - this->adj[city1].insert(city2); - } + public: + ConcreteRoadMap() : adj() {}; -public: - ConcreteRoadMap() : adj(), cities(0) {}; + void addRoad(const string& city1, const string& city2) override { + addPair(city1, city2); + addPair(city2, city1); + } - void addRoad(const string& city1, const string& city2) override { - addPair(city1, city2); - addPair(city2, city1); - } + void addRoad(const vector& cities) override { + for (size_t i = 0; i < cities.size() - 1; i++) { + addRoad(cities[i], cities[i + 1]); + } + } - void addRoad(const vector& cities) override { - for (size_t i = 0; i < cities.size() - 1; i++) { - addRoad(cities[i], cities[i + 1]); - } - } + void clear() override { + this->adj.clear(); + } - void clear() override { - this->adj.clear(); - } + int neighborCountForCity(const string& city) const override { + auto i = this->adj.find(city); + if (i == adj.end()) return -1; + return i->second.size(); + } - int neighborCountForCity(const string& city) const override { - auto i = this->adj.find(city); - return i->second.size(); - } + bool hasLoop() const override { + stack< std::pair > s; + set discovered; + bool search_comp; + + for (auto itr = adj.begin(); itr != adj.end(); ++itr) { + search_comp = true; + s.push(std::pair(itr->first, itr->first)); + while (!s.empty()) { + const std::pair v = s.top(); +#if DEBUG + std::cout << "Front is: " << v.first << " with parent " << + v.second << "\n"; +#endif + s.pop(); + if (discovered.find(v.first) == discovered.end()) { + search_comp = false; + discovered.insert(v.first); + const auto i = this->adj.find(v.first); + const auto set = i->second; + for (auto j = set.begin(); j != set.end(); ++j) { + if (*j != v.second) { +#if DEBUG + cout << "Neighbor: " << *j << " parent: " << + v.first << "\n"; +#endif + s.push(std::pair(*j, + v.first)); + } + } + } else if (!search_comp) { + // cout << v.first << " is discovered\n"; + return true; + } + } + } + return false; + } + + bool reachable(const string& c1, const string& c2) const override { + if (adj.find(c1) == adj.end() || + adj.find(c2) == adj.end()) { + return false; + } + + deque s; + set discovered; + s.push_back(c1); + while (!s.empty()) { + const string& v = s.front(); + if (v == c2) return true; + s.pop_front(); + + discovered.insert(v); + const auto i = this->adj.find(v); + const auto set = i->second; + for (auto j = set.begin(); j != set.end(); ++j) { + if (discovered.find(*j) == discovered.end()) { + s.push_back(*j); + } + } + } + return false; + } + + int countIslands() const override { + int islands = 0; + bool first; + + stack< std::pair > s; + set discovered; + + for (auto itr = adj.begin(); itr != adj.end(); ++itr) { + s.push(std::pair(itr->first, itr->first)); + first = true; + while (!s.empty()) { + const std::pair& v = s.top(); + s.pop(); + if (discovered.find(v.first) == discovered.end()) { + + if (first) { + islands++; + } + + discovered.insert(v.first); + const auto i = this->adj.find(v.first); + const auto set = i->second; + + for (auto j = set.begin(); j != set.end(); ++j) { + if (*j != v.second) { + s.push(std::pair(*j, v.first)); + } + } + } + + first = false; + } + } + + return islands; + } }; + +AbstractRoadMap* createRoadMap() { + return new ConcreteRoadMap(); +} diff --git a/roadmap/tests/test2.cpp b/roadmap/tests/test2.cpp index 74199e6..ca24e07 100644 --- a/roadmap/tests/test2.cpp +++ b/roadmap/tests/test2.cpp @@ -170,7 +170,7 @@ TEST(unknown_city) { std::vector cities = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" }; - for (unsigned int i = 0; i < cities.size(); ++i) + for (unsigned int i = 0; i < cities.size(); ++i) assert_int_eq(m->neighborCountForCity(cities[i]), -1); for (unsigned int i = 0; i < cities.size(); ++i)