1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#include <iostream>
#include <fstream>
#include <string>
#include <string_view>
#include <array>
#include <utility>
#include <algorithm>
#include <vector>
#include <cctype>
#include <limits>
enum Dir {
NORTH, SOUTH, EAST, WEST
};
enum Instruct {
MOVE, REPORT, LEFT, RIGHT, UP, DOWN
};
struct Pos {
std::pair<int, int> pos {};
Dir dir {};
};
struct Case {
Pos locPos, outPos;
std::vector<Instruct> instructs;
};
std::string& toUpper(std::string& s) {
for (auto& c : s)
c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
return s;
}
constexpr std::array<std::string_view, 4> dir { "NORTH", "SOUTH", "EAST", "WEST" };
constexpr std::array<std::string_view, 6> instruct { "MOVE", "REPORT", "LEFT", "RIGHT", "UP", "DOWN" };
std::istream& operator>>(std::istream& is, Pos& pos) {
std::string d;
if (char del {}; is >> pos.pos.first >> del >> pos.pos.second >> del >> d) {
if (const auto p { std::ranges::find(dir, toUpper(d)) }; p != dir.end())
pos.dir = Dir(p - dir.begin());
else {
std::cout << "Incorrect direction\n";
is.setstate(std::ios_base::badbit);
}
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return is;
}
std::ostream& operator<<(std::ostream& os, const Pos& pos) {
return os << pos.pos.first << ',' << pos.pos.second << ',' << dir[pos.dir];
}
std::istream& operator>>(std::istream& is, Case& cse) {
std::string str;
cse.instructs.clear();
if (is >> str; is && (str == "LOCATE"))
if (is >> cse.locPos) {
do {
if (is >> str; is && (toUpper(str) != "OUTPUT:")) {
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (const auto i { std::ranges::find(instruct, str) }; i != instruct.end())
cse.instructs.push_back(Instruct(i - instruct.begin()));
else {
std::cout << "Invalid instruction\n";
is.setstate(std::ios_base::badbit);
}
}
} while (is && (str != "OUTPUT:"));
is >> cse.outPos;
}
else if (is) {
std::cout << "LOCATE expected\n";
is.setstate(std::ios_base::badbit);
}
return is;
}
std::ostream& operator<<(std::ostream& os, const Case& cse) {
os << "LOCATE " << cse.locPos << '\n';
for (const auto& i : cse.instructs)
os << instruct[i] << '\n';
return os << "Output: " << cse.outPos;
}
int main() {
std::ifstream ifs("test.txt");
if (!ifs)
return (std::cout << "Can not open input file\n"), 1;
std::vector<Case> cases;
for (Case c; ifs >> c; cases.push_back(c));
for (const auto& c : cases)
std::cout << c << '\n';
}
|