#pragma once
#include <memory>
#include <cmath>
#include <string>


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

class Triangle : public Figure {
 public:
    double perim, area;
    Triangle(double a, double b, double c) {
        perim = a + b + c;
        double ger = perim / 2;
        area = sqrt(ger * (ger - a) * (ger - b) * (ger - c));
    }
    std::string Name() {
        return "TRIANGLE";
    }
    double Perimeter() {
        return perim;
    }
    double Area() {
        return area;
    }
};

class Rect : public Figure {
 public:
    double perim, area;
    Rect(double width, double height) {
        perim = 2 * (width + height);
        area = width * height;
    }
    std::string Name() {
        return "RECT";
    }
    double Perimeter() {
        return perim;
    }
    double Area() {
        return area;
    }
};

class Circle : public Figure {
 public:
    double perim, area;
    const double pi = 3.14;
    explicit Circle(double r) {
        perim = 2 * pi * r;
        area = pi * pow(r, 2);
    }
    std::string Name() {
        return "CIRCLE";
    }
    double Perimeter() {
        return perim;
    }
    double Area() {
        return area;
    }
};

std::shared_ptr<Figure> CreateFigure(std::istringstream& is) {
    using std::make_shared;
    std::string figure_t;
    int64_t a, b, c;
    is >> figure_t;
    if (figure_t == "RECT") {
        is >> a >> b;
        return make_shared<Rect>(a, b);
    } else if (figure_t == "TRIANGLE") {
        is >> a >> b >> c;
        return make_shared<Triangle>(a, b, c);
    } else {
        is >> a;
        return make_shared<Circle>(a);
    }
}