| marci@281 |      1 | // -*- c++ -*-
 | 
| marci@281 |      2 | #include <iostream>
 | 
| marci@281 |      3 | #include <vector>
 | 
| marci@281 |      4 | #include <string>
 | 
| marci@281 |      5 | 
 | 
| marci@281 |      6 | #include <list_graph.h>
 | 
| marci@281 |      7 | #include <smart_graph.h>
 | 
| marci@303 |      8 | #include <bfs_iterator_1.h>
 | 
| marci@303 |      9 | #include <graph_wrapper_1.h>
 | 
| marci@281 |     10 | 
 | 
| marci@281 |     11 | using namespace hugo;
 | 
| marci@281 |     12 | using std::cout; 
 | 
| marci@281 |     13 | using std::endl;
 | 
| marci@281 |     14 | using std::string;
 | 
| marci@281 |     15 | 
 | 
| marci@281 |     16 | template <typename Graph, typename NodeNameMap>
 | 
| marci@281 |     17 | class EdgeNameMap {
 | 
| marci@281 |     18 |   Graph& graph;
 | 
| marci@281 |     19 |   NodeNameMap& node_name_map;
 | 
| marci@281 |     20 | public:
 | 
| marci@281 |     21 |   EdgeNameMap(Graph& _graph, NodeNameMap& _node_name_map) : 
 | 
| marci@281 |     22 |     graph(_graph), node_name_map(_node_name_map) { }
 | 
| marci@281 |     23 |   string get(typename Graph::Edge e) const { 
 | 
| marci@281 |     24 |     return 
 | 
| marci@281 |     25 |       (node_name_map.get(graph.tail(e))+"->"+node_name_map.get(graph.head(e)));
 | 
| marci@281 |     26 |   }
 | 
| marci@281 |     27 | };
 | 
| marci@281 |     28 | 
 | 
| marci@281 |     29 | int main (int, char*[])
 | 
| marci@281 |     30 | {
 | 
| marci@281 |     31 |   //typedef SmartGraph Graph;
 | 
| marci@281 |     32 |   typedef ListGraph Graph;
 | 
| marci@281 |     33 | 
 | 
| marci@281 |     34 |   typedef Graph::Node Node;
 | 
| marci@281 |     35 |   typedef Graph::Edge Edge;
 | 
| marci@281 |     36 |  
 | 
| marci@281 |     37 |   Graph G;
 | 
| marci@281 |     38 | 
 | 
| marci@281 |     39 |   Node s=G.addNode();
 | 
| marci@281 |     40 |   Node v1=G.addNode();
 | 
| marci@281 |     41 |   Node v2=G.addNode();
 | 
| marci@281 |     42 |   Node v3=G.addNode();
 | 
| marci@281 |     43 |   Node v4=G.addNode();
 | 
| marci@281 |     44 |   Node t=G.addNode();
 | 
| marci@281 |     45 |   
 | 
| marci@281 |     46 |   Graph::NodeMap<string> node_name(G);
 | 
| marci@281 |     47 |   node_name.set(s, "s");
 | 
| marci@281 |     48 |   node_name.set(v1, "v1");
 | 
| marci@281 |     49 |   node_name.set(v2, "v2");
 | 
| marci@281 |     50 |   node_name.set(v3, "v3");
 | 
| marci@281 |     51 |   node_name.set(v4, "v4");
 | 
| marci@281 |     52 |   node_name.set(t, "t");
 | 
| marci@281 |     53 | 
 | 
| marci@281 |     54 |   G.addEdge(s, v1);
 | 
| marci@281 |     55 |   G.addEdge(s, v2);
 | 
| marci@281 |     56 |   G.addEdge(v1, v2);
 | 
| marci@281 |     57 |   G.addEdge(v2, v1);
 | 
| marci@281 |     58 |   G.addEdge(v1, v3);
 | 
| marci@281 |     59 |   G.addEdge(v3, v2);
 | 
| marci@281 |     60 |   G.addEdge(v2, v4);
 | 
| marci@281 |     61 |   G.addEdge(v4, v3);
 | 
| marci@281 |     62 |   G.addEdge(v3, t);
 | 
| marci@281 |     63 |   G.addEdge(v4, t);
 | 
| marci@281 |     64 | 
 | 
| marci@281 |     65 |   cout << "    /-->    ------------->            "<< endl;
 | 
| marci@281 |     66 |   cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
 | 
| marci@281 |     67 |   cout << "  / |          |    /  /->     \\     "<< endl;
 | 
| marci@281 |     68 |   cout << " /  |          |   /  |    ^    \\  "<< endl;
 | 
| marci@281 |     69 |   cout << "s   |          |  /   |    |     \\->  t "<< endl;
 | 
| marci@281 |     70 |   cout << " \\  |          | /    |    |     /->  "<< endl;
 | 
| marci@281 |     71 |   cout << "  \\ |       --/ /     |    |    /     "<< endl;
 | 
| marci@281 |     72 |   cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
 | 
| marci@281 |     73 |   cout << "    \\-->    ------------->         "<< endl;
 | 
| marci@281 |     74 |   
 | 
| marci@281 |     75 | //   typedef TrivGraphWrapper<const Graph> CGW;
 | 
| marci@281 |     76 | //   CGW gw(G);
 | 
| marci@281 |     77 | 
 | 
| marci@281 |     78 | //   cout << "bfs and dfs demo on the directed graph" << endl;
 | 
| marci@281 |     79 | //   for(CGW::NodeIt n=gw.first<CGW::NodeIt>(); n.valid(); ++n) { 
 | 
| marci@281 |     80 | //     cout << n << ": ";
 | 
| marci@281 |     81 | //     cout << "out edges: ";
 | 
| marci@281 |     82 | //     for(CGW::OutEdgeIt e=gw.first<CGW::OutEdgeIt>(n); e.valid(); ++e) 
 | 
| marci@281 |     83 | //       cout << e << " ";
 | 
| marci@281 |     84 | //     cout << "in edges: ";
 | 
| marci@281 |     85 | //     for(CGW::InEdgeIt e=gw.first<CGW::InEdgeIt>(n); e.valid(); ++e) 
 | 
| marci@281 |     86 | //       cout << e << " ";
 | 
| marci@281 |     87 | //     cout << endl;
 | 
| marci@281 |     88 | //   }
 | 
| marci@281 |     89 | 
 | 
| marci@281 |     90 |   {
 | 
| marci@281 |     91 |     typedef TrivGraphWrapper<const Graph> GW;
 | 
| marci@281 |     92 |     GW gw(G);
 | 
| marci@281 |     93 | 
 | 
| marci@281 |     94 |     EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
 | 
| marci@281 |     95 |     
 | 
| marci@281 |     96 |     cout << "bfs and dfs iterator demo on the directed graph" << endl;
 | 
| marci@281 |     97 |     for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
 | 
| marci@281 |     98 |       cout << node_name.get(n) << ": ";
 | 
| marci@281 |     99 |       cout << "out edges: ";
 | 
| marci@281 |    100 |       for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    101 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    102 |       cout << "in edges: ";
 | 
| marci@281 |    103 |       for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    104 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    105 |       cout << endl;
 | 
| marci@281 |    106 |     }
 | 
| marci@281 |    107 | 
 | 
| marci@281 |    108 |     cout << "bfs from s ..." << endl;
 | 
| marci@281 |    109 |     BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
 | 
| marci@281 |    110 |     bfs.pushAndSetReached(s);
 | 
| marci@281 |    111 |     while (!bfs.finished()) {
 | 
| marci@281 |    112 |       //cout << "edge: ";
 | 
| marci@281 |    113 |       if (gw.valid(bfs)) {
 | 
| marci@281 |    114 | 	cout << edge_name.get(bfs) << /*endl*/", " << 
 | 
| marci@281 |    115 | 	  node_name.get(gw.aNode(bfs)) << 
 | 
| marci@281 |    116 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    117 | 	  node_name.get(gw.bNode(bfs)) << 
 | 
| marci@281 |    118 | 	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    119 | 	   ": is not newly reached.");
 | 
| marci@281 |    120 |       } else { 
 | 
| marci@281 |    121 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    122 | 	  node_name.get(bfs.aNode()) << 
 | 
| marci@281 |    123 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    124 | 	  
 | 
| marci@281 |    125 | 	  "invalid.";
 | 
| marci@281 |    126 |       }
 | 
| marci@281 |    127 |       cout << endl;
 | 
| marci@281 |    128 |       ++bfs;
 | 
| marci@281 |    129 |     }
 | 
| marci@281 |    130 | 
 | 
| marci@281 |    131 |     cout << "    /-->    ------------->            "<< endl;
 | 
| marci@281 |    132 |     cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
 | 
| marci@281 |    133 |     cout << "  / |          |    /  /->     \\     "<< endl;
 | 
| marci@281 |    134 |     cout << " /  |          |   /  |    ^    \\  "<< endl;
 | 
| marci@281 |    135 |     cout << "s   |          |  /   |    |     \\->  t "<< endl;
 | 
| marci@281 |    136 |     cout << " \\  |          | /    |    |     /->  "<< endl;
 | 
| marci@281 |    137 |     cout << "  \\ |       --/ /     |    |    /     "<< endl;
 | 
| marci@281 |    138 |     cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
 | 
| marci@281 |    139 |     cout << "    \\-->    ------------->         "<< endl;
 | 
| marci@281 |    140 | 
 | 
| marci@281 |    141 |     cout << "dfs from s ..." << endl;
 | 
| marci@281 |    142 |     DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
 | 
| marci@281 |    143 |     dfs.pushAndSetReached(s);
 | 
| marci@281 |    144 |     while (!dfs.finished()) {
 | 
| marci@281 |    145 |       ++dfs;
 | 
| marci@281 |    146 |       //cout << "edge: ";
 | 
| marci@281 |    147 |       if (gw.valid(dfs)) {
 | 
| marci@281 |    148 | 	cout << edge_name.get(dfs) << /*endl*/", " << 
 | 
| marci@281 |    149 | 	  node_name.get(gw.aNode(dfs)) << 
 | 
| marci@281 |    150 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    151 | 	  node_name.get(gw.bNode(dfs)) << 
 | 
| marci@281 |    152 | 	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    153 | 	   ": is not newly reached.");
 | 
| marci@281 |    154 |       } else { 
 | 
| marci@281 |    155 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    156 | 	  node_name.get(dfs.aNode()) << 
 | 
| marci@281 |    157 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    158 | 	  
 | 
| marci@281 |    159 | 	  "invalid.";
 | 
| marci@281 |    160 |       }
 | 
| marci@281 |    161 |       cout << endl;
 | 
| marci@281 |    162 |     }
 | 
| marci@281 |    163 |   }
 | 
| marci@281 |    164 | 
 | 
| marci@281 |    165 | 
 | 
| marci@281 |    166 |   {
 | 
| marci@281 |    167 |     typedef RevGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
 | 
| marci@281 |    168 |     GW gw(G);
 | 
| marci@281 |    169 |     
 | 
| marci@281 |    170 |     EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
 | 
| marci@281 |    171 |     
 | 
| marci@281 |    172 |     cout << "bfs and dfs iterator demo on the reversed directed graph" << endl;
 | 
| marci@281 |    173 |     for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
 | 
| marci@281 |    174 |       cout << node_name.get(n) << ": ";
 | 
| marci@281 |    175 |       cout << "out edges: ";
 | 
| marci@281 |    176 |       for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    177 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    178 |       cout << "in edges: ";
 | 
| marci@281 |    179 |       for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    180 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    181 |       cout << endl;
 | 
| marci@281 |    182 |     }
 | 
| marci@281 |    183 | 
 | 
| marci@281 |    184 |     cout << "bfs from t ..." << endl;
 | 
| marci@281 |    185 |     BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
 | 
| marci@281 |    186 |     bfs.pushAndSetReached(t);
 | 
| marci@281 |    187 |     while (!bfs.finished()) {
 | 
| marci@281 |    188 |       //cout << "edge: ";
 | 
| marci@281 |    189 |       if (gw.valid(bfs)) {
 | 
| marci@281 |    190 | 	cout << edge_name.get(bfs) << /*endl*/", " << 
 | 
| marci@281 |    191 | 	  node_name.get(gw.aNode(bfs)) << 
 | 
| marci@281 |    192 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    193 | 	  node_name.get(gw.bNode(bfs)) << 
 | 
| marci@281 |    194 | 	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    195 | 	   ": is not newly reached.");
 | 
| marci@281 |    196 |       } else { 
 | 
| marci@281 |    197 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    198 | 	  node_name.get(bfs.aNode()) << 
 | 
| marci@281 |    199 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    200 | 	  
 | 
| marci@281 |    201 | 	  "invalid.";
 | 
| marci@281 |    202 |       }
 | 
| marci@281 |    203 |       cout << endl;
 | 
| marci@281 |    204 |       ++bfs;
 | 
| marci@281 |    205 |     }
 | 
| marci@281 |    206 | 
 | 
| marci@281 |    207 |     cout << "    /-->    ------------->            "<< endl;
 | 
| marci@281 |    208 |     cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
 | 
| marci@281 |    209 |     cout << "  / |          |    /  /->     \\     "<< endl;
 | 
| marci@281 |    210 |     cout << " /  |          |   /  |    ^    \\  "<< endl;
 | 
| marci@281 |    211 |     cout << "s   |          |  /   |    |     \\->  t "<< endl;
 | 
| marci@281 |    212 |     cout << " \\  |          | /    |    |     /->  "<< endl;
 | 
| marci@281 |    213 |     cout << "  \\ |       --/ /     |    |    /     "<< endl;
 | 
| marci@281 |    214 |     cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
 | 
| marci@281 |    215 |     cout << "    \\-->    ------------->         "<< endl;
 | 
| marci@281 |    216 |     
 | 
| marci@281 |    217 |     cout << "dfs from t ..." << endl;
 | 
| marci@281 |    218 |     DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
 | 
| marci@281 |    219 |     dfs.pushAndSetReached(t);
 | 
| marci@281 |    220 |     while (!dfs.finished()) {
 | 
| marci@281 |    221 |       ++dfs;
 | 
| marci@281 |    222 |       //cout << "edge: ";
 | 
| marci@281 |    223 |       if (gw.valid(dfs)) {
 | 
| marci@281 |    224 | 	cout << edge_name.get(dfs) << /*endl*/", " << 
 | 
| marci@281 |    225 | 	  node_name.get(gw.aNode(dfs)) << 
 | 
| marci@281 |    226 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    227 | 	  node_name.get(gw.bNode(dfs)) << 
 | 
| marci@281 |    228 | 	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    229 | 	   ": is not newly reached.");
 | 
| marci@281 |    230 |       } else { 
 | 
| marci@281 |    231 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    232 | 	  node_name.get(dfs.aNode()) << 
 | 
| marci@281 |    233 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    234 | 	  
 | 
| marci@281 |    235 | 	  "invalid.";
 | 
| marci@281 |    236 |       }
 | 
| marci@281 |    237 |       cout << endl;
 | 
| marci@281 |    238 |     }
 | 
| marci@281 |    239 |   }
 | 
| marci@281 |    240 | 
 | 
| marci@281 |    241 |   {
 | 
| marci@281 |    242 |     //typedef UndirGraphWrapper<const Graph> GW;
 | 
| marci@281 |    243 |     typedef UndirGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
 | 
| marci@281 |    244 |     GW gw(G);
 | 
| marci@281 |    245 |     
 | 
| marci@281 |    246 |     EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
 | 
| marci@281 |    247 |     
 | 
| marci@281 |    248 |     cout << "bfs and dfs iterator demo on the undirected graph" << endl;
 | 
| marci@281 |    249 |     for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
 | 
| marci@281 |    250 |       cout << node_name.get(n) << ": ";
 | 
| marci@281 |    251 |       cout << "out edges: ";
 | 
| marci@281 |    252 |       for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    253 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    254 |       cout << "in edges: ";
 | 
| marci@281 |    255 |       for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
 | 
| marci@281 |    256 | 	cout << edge_name.get(e) << " ";
 | 
| marci@281 |    257 |       cout << endl;
 | 
| marci@281 |    258 |     }
 | 
| marci@281 |    259 | //     for(GW::EdgeIt e=gw.first<GW::EdgeIt>(); gw.valid(e); gw.next(e)) { 
 | 
| marci@281 |    260 | //       cout << edge_name.get(e) << " ";
 | 
| marci@281 |    261 | //     }
 | 
| marci@281 |    262 | //     cout << endl;
 | 
| marci@281 |    263 | 
 | 
| marci@281 |    264 |     cout << "bfs from t ..." << endl;
 | 
| marci@281 |    265 |     BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
 | 
| marci@281 |    266 |     bfs.pushAndSetReached(t);
 | 
| marci@281 |    267 |     while (!bfs.finished()) {
 | 
| marci@281 |    268 |       //cout << "edge: ";
 | 
| marci@281 |    269 |       if (gw.valid(GW::OutEdgeIt(bfs))) {
 | 
| marci@281 |    270 | 	cout << edge_name.get(GW::OutEdgeIt(bfs)) << /*endl*/", " << 
 | 
| marci@281 |    271 | 	  node_name.get(gw.aNode(bfs)) << 
 | 
| marci@281 |    272 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    273 | 	  node_name.get(gw.bNode(bfs)) << 
 | 
| marci@281 |    274 | 	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    275 | 	   ": is not newly reached.");
 | 
| marci@281 |    276 |       } else { 
 | 
| marci@281 |    277 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    278 | 	  node_name.get(bfs.aNode()) << 
 | 
| marci@281 |    279 | 	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    280 | 	  
 | 
| marci@281 |    281 | 	  "invalid.";
 | 
| marci@281 |    282 |       }
 | 
| marci@281 |    283 |       cout << endl;
 | 
| marci@281 |    284 |       ++bfs;
 | 
| marci@281 |    285 |     }
 | 
| marci@281 |    286 | 
 | 
| marci@281 |    287 |     cout << "    /-->    ------------->            "<< endl;
 | 
| marci@281 |    288 |     cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
 | 
| marci@281 |    289 |     cout << "  / |          |    /  /->     \\     "<< endl;
 | 
| marci@281 |    290 |     cout << " /  |          |   /  |    ^    \\  "<< endl;
 | 
| marci@281 |    291 |     cout << "s   |          |  /   |    |     \\->  t "<< endl;
 | 
| marci@281 |    292 |     cout << " \\  |          | /    |    |     /->  "<< endl;
 | 
| marci@281 |    293 |     cout << "  \\ |       --/ /     |    |    /     "<< endl;
 | 
| marci@281 |    294 |     cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
 | 
| marci@281 |    295 |     cout << "    \\-->    ------------->         "<< endl;
 | 
| marci@281 |    296 |     
 | 
| marci@281 |    297 |     cout << "dfs from t ..." << endl;
 | 
| marci@281 |    298 |     DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
 | 
| marci@281 |    299 |     dfs.pushAndSetReached(t);
 | 
| marci@281 |    300 |     while (!dfs.finished()) {
 | 
| marci@281 |    301 |       ++dfs;
 | 
| marci@281 |    302 |       //cout << "edge: ";
 | 
| marci@281 |    303 |       if (gw.valid(GW::OutEdgeIt(dfs))) {
 | 
| marci@281 |    304 | 	cout << edge_name.get(GW::OutEdgeIt(dfs)) << /*endl*/", " << 
 | 
| marci@281 |    305 | 	  node_name.get(gw.aNode(dfs)) << 
 | 
| marci@281 |    306 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    307 | 	  node_name.get(gw.bNode(dfs)) << 
 | 
| marci@281 |    308 | 	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
 | 
| marci@281 |    309 | 	   ": is not newly reached.");
 | 
| marci@281 |    310 |       } else { 
 | 
| marci@281 |    311 | 	cout << "invalid" << /*endl*/", " << 
 | 
| marci@281 |    312 | 	  node_name.get(dfs.aNode()) << 
 | 
| marci@281 |    313 | 	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
 | 
| marci@281 |    314 | 	  
 | 
| marci@281 |    315 | 	  "invalid.";
 | 
| marci@281 |    316 |       }
 | 
| marci@281 |    317 |       cout << endl;
 | 
| marci@281 |    318 |     }
 | 
| marci@281 |    319 |   }
 | 
| marci@281 |    320 | 
 | 
| marci@281 |    321 |   return 0;
 | 
| marci@281 |    322 | }
 |