Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions polevshikov.vladislav/T3/commands.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#include "commands.h"
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <limits>

bool checkAndConsumeRestOfLine(std::istream& in) {
while (in.peek() == ' ' || in.peek() == '\t') {
in.get();
}
char next = in.peek();
if (next == '\n' || next == EOF) {
if (next == '\n') {
in.get();
}
return true;
}
return false;
}

void doArea(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
std::string subCmd;
if (!(in >> subCmd) || !checkAndConsumeRestOfLine(in)) {
throw std::invalid_argument("extra symbols");
}

double res = 0.0;
if (subCmd == "EVEN") {
std::vector<Polygon> filtered;

std::copy_if(polygons.begin(), polygons.end(), std::back_inserter(filtered), isEven);
res = std::accumulate(filtered.begin(), filtered.end(), 0.0, sumArea);

} else if (subCmd == "ODD") {
std::vector<Polygon> filtered;

std::copy_if(polygons.begin(), polygons.end(), std::back_inserter(filtered), isOdd);
res = std::accumulate(filtered.begin(), filtered.end(), 0.0, sumArea);

} else if (subCmd == "MEAN") {
if (polygons.empty()) {
throw std::logic_error("Empty collection");
}

res = std::accumulate(polygons.begin(), polygons.end(), 0.0, sumArea) / polygons.size();

} else {
try {
size_t pos = 0;
long long val = std::stoll(subCmd, &pos);
if (pos != subCmd.size() || val < 3) {
printError(out);
return;
}

size_t num = static_cast<size_t>(val);
std::vector<Polygon> filtered;
std::copy_if(polygons.begin(), polygons.end(), std::back_inserter(filtered), HasNVertices{num});
res = std::accumulate(filtered.begin(), filtered.end(), 0.0, sumArea);

} catch (const std::exception&) {
printError(out);
return;
}
}
out << std::fixed << std::setprecision(1) << res << '\n';
}

void doMax(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
if (polygons.empty()) {
throw std::logic_error("Empty collection");
}

std::string subCmd;
if (!(in >> subCmd) || !checkAndConsumeRestOfLine(in)) {
throw std::invalid_argument("extra symbols");
}

if (subCmd == "AREA") {
auto it = std::max_element(polygons.begin(), polygons.end(), compareByArea);
out << std::fixed << std::setprecision(1) << getArea(*it) << '\n';

} else if (subCmd == "VERTEXES") {
auto it = std::max_element(polygons.begin(), polygons.end(), compareBySize);
out << it->points.size() << "\n";

} else {
throw std::invalid_argument("bad subcommand");
}
}

void doMin(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
if (polygons.empty()) {
throw std::logic_error("Empty collection");
}

std::string subCmd;
if (!(in >> subCmd) || !checkAndConsumeRestOfLine(in)) {
throw std::invalid_argument("extra symbols");
}

if (subCmd == "AREA") {
auto it = std::min_element(polygons.begin(), polygons.end(), compareByArea);
out << std::fixed << std::setprecision(1) << getArea(*it) << '\n';

} else if (subCmd == "VERTEXES") {
auto it = std::min_element(polygons.begin(), polygons.end(), compareBySize);
out << it->points.size() << "\n";

} else {
throw std::invalid_argument("bad subcommand");
}
}

void doCount(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
std::string subCmd;
if (!(in >> subCmd) || !checkAndConsumeRestOfLine(in)) {
throw std::invalid_argument("extra symbols");
}

size_t cnt = 0;

if (subCmd == "EVEN") {
cnt = std::count_if(polygons.begin(), polygons.end(), isEven);

} else if (subCmd == "ODD") {
cnt = std::count_if(polygons.begin(), polygons.end(), isOdd);

} else {
try {
size_t pos = 0;
long long val = std::stoll(subCmd, &pos);
if (pos != subCmd.size() || val < 3) {
printError(out);
return;
}

size_t num = static_cast<size_t>(val);
cnt = std::count_if(polygons.begin(), polygons.end(), HasNVertices{num});

} catch (std::exception&) {
printError(out);
return;
}
}
out << cnt << '\n';
}

void printError(std::ostream& out) {
out << "<INVALID COMMAND>\n";
}

void doRightShapes(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
if (!checkAndConsumeRestOfLine(in)) {
printError(out);
return;
}

long long count = std::count_if(polygons.begin(), polygons.end(), hasRightAngle);
out << count << '\n';
}

void doInFrame(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out) {
Polygon target;
if (!(in >> target) || !checkAndConsumeRestOfLine(in)) {
in.clear();
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
printError(out);
return;
}

if (polygons.empty()) {
throw std::logic_error("Empty collection");
}

int minX = std::accumulate(polygons.begin(), polygons.end(), std::numeric_limits<int>::max(), getMinX);
int maxX = std::accumulate(polygons.begin(), polygons.end(), std::numeric_limits<int>::min(), getMaxX);
int minY = std::accumulate(polygons.begin(), polygons.end(), std::numeric_limits<int>::max(), getMinY);
int maxY = std::accumulate(polygons.begin(), polygons.end(), std::numeric_limits<int>::min(), getMaxY);

bool inInside = std::all_of(target.points.begin(), target.points.end(), [minX, maxX, minY, maxY](const Point& p) {
return p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY;
});
out << (inInside ? "<TRUE>" : "<FALSE>") << '\n';
}
18 changes: 18 additions & 0 deletions polevshikov.vladislav/T3/commands.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef COMMANDS_H
#define COMMANDS_H

#include <vector>
#include <string>
#include <iostream>
#include "polygon.h"

void doArea(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);
void doMax(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);
void doMin(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);
void doCount(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);
void doInFrame(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);
void doRightShapes(const std::vector<Polygon>& polygons, std::istream& in, std::ostream& out);

void printError(std::ostream& out);

#endif
63 changes: 63 additions & 0 deletions polevshikov.vladislav/T3/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <functional>
#include <limits>
#include "polygon.h"
#include "commands.h"

using namespace std::placeholders;

int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <filename>\n";
return 1;
}

std::ifstream file(argv[1]);
if (!file.is_open()) {
std::cerr << "Cannot open file: " << argv[1] << '\n';
return 1;
}

std::vector<Polygon> polygons;

while (file) {
Polygon p;
if (file >> p) {
polygons.push_back(p);
} else if (!file.eof()) {
file.clear();
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}

std::map<std::string, std::function<void(std::istream&, std::ostream&)>> cmds;

cmds["AREA"] = std::bind(doArea, std::cref(polygons), _1, _2);
cmds["MAX"] = std::bind(doMax, std::cref(polygons), _1, _2);
cmds["MIN"] = std::bind(doMin, std::cref(polygons), _1, _2);
cmds["COUNT"] = std::bind(doCount, std::cref(polygons), _1, _2);
cmds["RIGHTSHAPES"] = std::bind(doRightShapes, std::cref(polygons), _1, _2);
cmds["INFRAME"] = std::bind(doInFrame, std::cref(polygons), _1, _2);

std::string cmd;
while(std::cin >> cmd) {
try {
if (cmds.count(cmd)) {
cmds[cmd](std::cin, std::cout);
} else {
printError(std::cout);
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

} catch (...) {
printError(std::cout);
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
return 0;
}
Loading
Loading