Skip to content

Commit

Permalink
Progress with requirement 5
Browse files Browse the repository at this point in the history
  • Loading branch information
jakedcolbert committed May 4, 2022
1 parent dbbc889 commit c26b8d5
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 70 deletions.
67 changes: 63 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,74 @@
# Author: Elijah Opoku-Nyarko and Jake Colbert

# define colors
ifneq (,$(findstring xterm,${TERM}))
RED := $(shell tput -Txterm setaf 1)
GREEN := $(shell tput -Txterm setaf 2)
RESET := $(shell tput -Txterm sgr0)
else
RED := ""
GREEN := ""
RESET := ""
endif

# default target
all: project5

# compile the code into an executable called 'project1' using C++ 2011
project5: project5.cc province.cc province.h
g++ -std=c++11 -o project5 project5.cc province.cc

# test the code against an expected output file
# this test should grow into a spaceship and end with blinkers
test-requirement1: project5
# test all the code
test-all: project5 test-nowhere test-one-road test-simple test-local test-combo
@echo ""
@echo "$(GREEN)Passed all tests!$(RESET)"
@echo ""

test: project5
./project5 < test-data/t0502-combo.in > test-data/project5.out
diff test-data/project5.out test-data/shortest.out > test.diff
rm test-data/project5.out

# test the code against an expected output file
test-nowhere: project5
@echo ""
@echo "$(RED)--- Nowhere Test ---$(RESET)"
@echo ""
./project5 < test-data/t01-nowhere.in > test-data/project5.out
diff test-data/project5.out test-data/t01-nowhere.out > test.diff
@echo "$(GREEN)Passed!$(RESET)"

# test the code against an expected output file
test-one-road: project5
@echo ""
@echo "$(RED)--- One Road Test ---$(RESET)"
@echo ""
./project5 < test-data/t02-one-road.in > test-data/project5.out
diff test-data/project5.out test-data/t02-one-road.out > test.diff
@echo "$(GREEN)Passed!$(RESET)"

# test the code against an expected output file
test-simple: project5
@echo ""
@echo "$(RED)--- Simple Test ---$(RESET)"
@echo ""
./project5 < test-data/t03-simple.in > test-data/project5.out
diff test-data/project5.out test-data/t03-simple.out > test.diff
@echo "$(GREEN)Passed!$(RESET)"

# test the code against an expected output file
test-local: project5
@echo ""
@echo "$(RED)--- Local Test ---$(RESET)"
@echo ""
./project5 < test-data/t08-local.in > test-data/project5.out
diff test-data/project5.out test-data/t08-local.out > test.diff
@echo "$(GREEN)Passed!$(RESET)"

# test the code against an expected output file
test-combo: project5
@echo ""
@echo "$(RED)--- Combo Test ---$(RESET)"
@echo ""
./project5 < test-data/t0502-combo.in > test-data/project5.out
diff test-data/project5.out test-data/t0502-combo.out > test.diff
@echo "$(GREEN)Passed!$(RESET)"
Binary file modified project5
Binary file not shown.
4 changes: 3 additions & 1 deletion project5.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ int main(int argc, char *argv[]) {
theProvince.printAll(0, cout);
theProvince.printShortestPath(std::cout);
theProvince.minSpan(std::cout);
theProvince.removeBridges(cout);
theProvince.articulationPoints(cout);
std::cout << std::endl;
std::cout << "------------------------------------------------------------------";
std::cout << endl;
cout << endl << endl;
}
}
172 changes: 107 additions & 65 deletions province.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

using namespace std;

/*f
/*
* Constructor
* @param source File containing province:
* 1. One line: number of towns (n), number of roads (p)
Expand All @@ -32,48 +32,27 @@ Province::Province(std::istream & source) {

// Read town names
for (int i = 0; i < _numberOfTowns; i++) {
source >> _towns[i]._name; // This needs to be converted to vector, im not sure how exactly
//cout << "This is the name: " << &_towns[i]._name << endl;
source >> _towns[i]._name;
townMap[_towns[i]._name] = i;
}

// Read roads
for (int i = 0; i < _numberOfRoads; i++) {
std::string tail, head;
source >> tail >> head;
int tailIndex = townMap[tail]; // index of the first town
int headIndex = townMap[head]; // index of the second town

// Get the type of road ("B" If Bridge, "N" if normal road)
char type;
source >> type;
bool isBridge = (type == 'B');
// Not sure how to Get the type if it is a normal road (ie. Not a Bridge)

// Length of road
double length;
source >> length;

// Add a road to the road list
Road newRoad(headIndex, tailIndex, isBridge, length);
_roads.push_back(newRoad);

// Add a road to two connecting towns
_towns[tailIndex]._roads.push_back(Road(headIndex, tailIndex,
isBridge, length));
_towns[headIndex]._roads.push_back(Road(tailIndex, headIndex,
isBridge, length));


string tail, head;
char bridgeFlag;
double length;
source >> tail >> head >> bridgeFlag >> length;
bool isBridge = (bridgeFlag == 'B');
_roads.push_back(Road(townMap.at(head), townMap.at(tail), isBridge, length));
_towns[townMap.at(tail)]._roads.push_back(Road(townMap.at(head), townMap.at(tail), isBridge, length));
_towns[townMap.at(head)]._roads.push_back(Road(townMap.at(tail), townMap.at(head), isBridge, length));
}
}

void Province::printAll(int start, std::ostream & output) {
// keep track of whether a town(vertex) has been scheduled to be visited
bool scheduled[_numberOfTowns];
for (int i = 0; i < _numberOfTowns; i++){
scheduled[i] = false;
}
memset(scheduled, 0, sizeof scheduled); // initialize to 0/false

// Keep track of which towns have been visited
queue <int> toVisit; // use queue to keep track of which town to visit next
Expand Down Expand Up @@ -147,13 +126,6 @@ void Province::printShortestPath(std::ostream & output) const {
output << "The shortest paths from " + _towns[0]._name;
output << " are:" << std::endl << std::endl;

// keeps track of the index of the predecessor to each
// town(vertex) n on the shortest path to n
int prev[_numberOfTowns];

output << "The shortest routes from " + _towns[0]._name;
output << " are:" << std::endl << std::endl;

// keeps track of the index of the predecessor to each
// town(vertex) n on the shortest path to n
int prev[_numberOfTowns];
Expand Down Expand Up @@ -311,15 +283,18 @@ void Province::minSpan(std::ostream & output) const {
}
}

output << "The road upgrading goal can be achieved at minimal cost by upgrading:";
output << std::endl;

// Print names of towns in minimum spanning tree of province
for (int i = 0; i < minSpanTree.size(); i++) {
output << " ";
output << _towns[minSpanTree[i]._head]._name;
output << " to ";
output << _towns[minSpanTree[i]._tail]._name << std::endl;
output << "The road upgrading goal can be achieved at minimal cost by upgrading:";
output << std::endl;

// Print names of towns in minimum spanning tree of province
for (int i = 0; i < minSpanTree.size(); i++) {
output << " ";
output << _towns[minSpanTree[i]._head]._name;
output << " to ";
output << _towns[minSpanTree[i]._tail]._name << std::endl;
}
output << endl;
}

std::vector<int> Province::bfs(int start) const {
// Initialize list of towns scheduled to visit
Expand Down Expand Up @@ -374,26 +349,14 @@ void Province::removeBridges(ostream &output) const {
break;
}
}
// If only one town
if (_numberOfTowns == 1) {
output << "There is only one town, so the province "
<< "will not be affected by a major storm";
return;

// If province has no bridge
} else if (!hasBridge) {
output << "The province has no bridges, so it "
<< "will not be affected by a major storm";
return;
}

// Mark all towns as unvisited
list<int> toVisit;
for (int i = 0; i < _numberOfTowns; i++) {
toVisit.push_back(i);
}
output << "Connected components in event of a major storm are: ";
output << endl << endl;
output << "Connected components in event of a major storm are:";
output << endl;

while (!toVisit.empty()) {
// Mark current town as visited
Expand All @@ -408,16 +371,95 @@ void Province::removeBridges(ostream &output) const {
toVisit.remove(bfsResult[i]);
}

output << " ";
output << " ";
output << "If all bridges fail, the following towns would form ";
output << "an isolated group:" << endl;

// Print names of all towns in connected component
for (int i = 0; i < bfsResult.size(); i++) {
output << " ";
output << " ";
output << _towns[bfsResult[i]]._name << endl;
}
output << endl;
}

}

void Province::APUtil(int u, bool visited[],
int disc[], int low[], int& time, int parent,
bool isAP[]) const {
// Count of children in DFS Tree
int children = 0;

// Mark the current node as visited
visited[u] = true;

// Initialize discovery time and low value
disc[u] = low[u] = ++time;

// Go through all vertices adjacent to this
for (int v = 0; v < _numberOfTowns; v++) {
// If v is not visited yet, then make it a child of u
// in DFS tree and recur for it
if (!visited[v]) {
children++;
APUtil(v, visited, disc, low, time, u, isAP);

// Check if the subtree rooted with v has
// a connection to one of the ancestors of u
low[u] = min(low[u], low[v]);

// If u is not root and low value of one of
// its child is more than discovery value of u.
if (parent != -1 && low[v] >= disc[u]) {
isAP[u] = true;
}
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}

// If u is root of DFS tree and has two or more children.
if (parent == -1 && children > 1) {
isAP[u] = true;
}
}

void Province::articulationPoints(std::ostream & output) const
{
int disc[_numberOfTowns];
memset(disc, 0, sizeof disc);
int low[_numberOfTowns];
bool visited[_numberOfTowns];
memset(visited, false, sizeof visited);
bool isAP[_numberOfTowns];
memset(isAP, false, sizeof isAP);
int time = 0, par = -1;

// Adding this loop so that the
// code works even if we are given
// disconnected graph
for (int u = 0; u < _numberOfTowns; u++) {
if (!visited[u]) {
APUtil(u, visited, disc, low,
time, par, isAP);
}
}
output << "Destruction of any of the following would result in the province becoming" << endl << "disconnected:" << endl;

int count = 0;
// Printing the APs
for (int u = 0; u < _numberOfTowns; u++) {
if (isAP[u] == true) {
output << " " << _towns[u]._name << endl;
count++;
}
}
if (count == 0) {
output << " (None)" << endl;
}
output << endl;

for (bool i : isAP) {
cerr << i << endl;
}
}
4 changes: 4 additions & 0 deletions province.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ class Province
* @return - List of indices of towns in order of traversal
*/
std::vector<int> bfs(int start) const;

void APUtil(int u, bool visited[],
int disc[], int low[], int& time, int parent,
bool isAP[]) const;

void dfsAux(int current, std::vector<int> & dfsTowns, bool visited []) const;

Expand Down
27 changes: 27 additions & 0 deletions test-data/project5.out
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ The shortest paths from Wenham are:
The road upgrading goal can be achieved at minimal cost by upgrading:
Hamilton to Wenham

Connected components in event of a major storm are:
If all bridges fail, the following towns would form an isolated group:
Hamilton
Wenham

Destruction of any of the following would result in the province becoming
disconnected:
(None)


------------------------------------------------------------------

The input data is:

A
Expand All @@ -39,4 +50,20 @@ The road upgrading goal can be achieved at minimal cost by upgrading:
B to A
C to B

Connected components in event of a major storm are:
If all bridges fail, the following towns would form an isolated group:
C

If all bridges fail, the following towns would form an isolated group:
B

If all bridges fail, the following towns would form an isolated group:
A

Destruction of any of the following would result in the province becoming
disconnected:
(None)


------------------------------------------------------------------

Loading

0 comments on commit c26b8d5

Please sign in to comment.