airport_routes.cpp
This commit is contained in:
178
puzzles/training/airport_routes.cpp
Normal file
178
puzzles/training/airport_routes.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
|
||||
VIM: let b:cf5run="{OUT}"
|
||||
VIM-: let b:cppflags=g:Iboost.g:Itbb
|
||||
VIM-: let b:ldflags=g:Lboost.g:Ltbb
|
||||
VIM-: let b:ldlibpath=g:Bboost.g:Btbb
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <functional>
|
||||
|
||||
/*
|
||||
Implement a class called AirMap that has two methods:
|
||||
|
||||
1- add_route(start, destination)
|
||||
- adds a ONE WAY connecting flight from start to destination
|
||||
|
||||
2- print_all_routes(start, destination)
|
||||
- prints all possible routes from start to destination irrespective of hops
|
||||
|
||||
Sample inputs - Expected outputs
|
||||
Given the following flight routes, print all possible routes between the airports C and D
|
||||
|
||||
A ----> B
|
||||
B ----> A
|
||||
A ----> C
|
||||
C ----> A
|
||||
A ----> D
|
||||
D ----> A
|
||||
B ----> C
|
||||
C ----> B
|
||||
B ----> D
|
||||
D ----> B
|
||||
Expected output:
|
||||
|
||||
C,A,B,D,
|
||||
C,A,D,
|
||||
C,B,A,D,
|
||||
C,B,D,
|
||||
|
||||
Input corner cases
|
||||
Find all routes from A to C
|
||||
|
||||
No route example:
|
||||
|
||||
A ----> B
|
||||
C ----> B
|
||||
C ----> A
|
||||
|
||||
Expected output:
|
||||
|
||||
"No route was found" message or an empty output
|
||||
Source equals destination example: Find all routes from A to A
|
||||
|
||||
A ----> B
|
||||
B ----> C
|
||||
C ----> A
|
||||
Expected output:
|
||||
|
||||
A
|
||||
*/
|
||||
|
||||
class AirMap
|
||||
{
|
||||
std::unordered_map<std::string, std::unordered_set<std::string>> graph_;
|
||||
|
||||
public:
|
||||
void add_route(const std::string& start, const std::string& destination)
|
||||
{
|
||||
graph_[start].insert(destination);
|
||||
}
|
||||
|
||||
void print_all_routes(
|
||||
const std::string& start,
|
||||
const std::string& destination) const
|
||||
{
|
||||
std::unordered_set<std::string> visited;
|
||||
std::vector<std::string> path;
|
||||
|
||||
print_all_routes_helper(start, destination, visited, path,
|
||||
[](const std::vector<std::string>& path){
|
||||
for (const auto& node : path){
|
||||
std::cout << node << ',';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
void print_all_routes_helper(
|
||||
const std::string& start,
|
||||
const std::string& destination,
|
||||
std::unordered_set<std::string>& visited,
|
||||
std::vector<std::string>& path,
|
||||
std::function<void (const std::vector<std::string>& path)> fn) const
|
||||
{
|
||||
visited.insert(start);
|
||||
path.push_back(start);
|
||||
|
||||
if (start == destination){
|
||||
fn(path);
|
||||
} else {
|
||||
const auto it = graph_.find(start);
|
||||
if ( it != graph_.end()){
|
||||
for (const auto& node : it->second){
|
||||
if ( !visited.contains(node) ){
|
||||
print_all_routes_helper(node, destination, visited, path, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visited.erase(start);
|
||||
path.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
int main ( void )
|
||||
{try{
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
||||
AirMap map;
|
||||
map.add_route("A","B");
|
||||
map.add_route("B","A");
|
||||
map.add_route("B","D");
|
||||
map.add_route("A","D");
|
||||
map.add_route("A","C");
|
||||
map.add_route("C","A");
|
||||
map.add_route("C","B");
|
||||
map.add_route("B","C");
|
||||
map.add_route("D","A");
|
||||
map.add_route("D","B");
|
||||
|
||||
map.print_all_routes("C", "D");
|
||||
//......
|
||||
|
||||
{
|
||||
std::cout << "---------------------------------------" << std::endl;
|
||||
AirMap map;
|
||||
map.add_route("A","B");
|
||||
map.add_route("C","A");
|
||||
map.add_route("C","B");
|
||||
map.print_all_routes("A", "C");
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "---------------------------------------" << std::endl;
|
||||
AirMap map;
|
||||
map.add_route("A","B");
|
||||
map.add_route("B","C");
|
||||
map.add_route("C","A");
|
||||
map.print_all_routes("A", "A");
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> seconds = end - begin;
|
||||
std::cout << "Time: " << seconds.count() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "std::exception(\"" << e.what() << "\")." << std::endl;
|
||||
return 2;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cerr << std::endl
|
||||
<< "unknown exception." << std::endl;
|
||||
return 1;
|
||||
}}
|
||||
Reference in New Issue
Block a user