#include "memory"
#include "cmath"

class Figure {
public:
  virtual std::string Name() = 0;
  virtual double Perimeter() = 0;
  virtual double Area() = 0;
};

class Rect : public Figure {
public:
  double width, height;
  std::string name = "RECT";
  Rect(double i_width, double i_height) {
	  width = i_width;
	  height = i_height;
  }

  std::string Name() override {
	  return name;
  }
  double Perimeter() override {
	  return (width + height) * 2;
  }
  double Area() override {
	  return width * height;
  }
};

class Triangle : public Figure {
public:
  double a, b, c;
  std::string name = "TRIANGLE";
  Triangle(double i_a, double i_b, double i_c) {
	  a = i_a;
	  b = i_b;
	  c = i_c;
  }

  std::string Name() override {
	  return name;
  }
  double Perimeter() override {
	  return a + b + c;
  }
  double Area() override {
	  double p = Perimeter() / 2;
	  return sqrt(p * (p - a) * (p - b) * (p - c));
  }
};

class Circle : public Figure {
public:
  double r;
  const double pi = 3.14;
  std::string name = "CIRCLE";
  explicit Circle(double i_r) {
	  r = i_r;
  }

  std::string Name() override {
	  return name;
  }
  double Perimeter() override {
	  return 2 * pi * r;
  }
  double Area() override {
	  return pi * pow(r, 2);
  }
};

std::shared_ptr<Figure> CreateFigure(std::istringstream &is) {
	std::string figure;
	is >> figure;
	
	if (figure == "RECT") {
		double width, height;
		is >> width >> height;
		return std::make_shared<Rect>(width, height);
	}
	else if (figure == "TRIANGLE") {
		double a, b, c;
		is >> a >> b >> c;
		return std::make_shared<Triangle>(a, b, c);
	}
	else if (figure == "CIRCLE") {
		double r;
		is >> r;
		return std::make_shared<Circle>(r);
	}
}