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

using namespace std;

double pi = 3.14;

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

class Triangle : public Figure {
public:
    double a;
    double b;
    double c;

    Triangle(double a1, double b1, double c1) : a(a1), b(b1), c(c1) {}

    string Name() const {
        return "TRIANGLE";
    }

    double Perimeter() const {
        return a + b + c;
    }

    double Area() const {
        double p = Perimeter() / 2;
        return sqrt(p * (p - a) * (p - b) * (p - c));
    }
};

class Rect : public Figure {
public:
    double w;
    double h;

    Rect(double w1, double h1) : w(w1), h(h1) {}

    string Name() const { 
        return "RECT";
    }

    double Area() const {
        return w * h;
    }

    double Perimeter() const {
        return 2 * (w + h);
    }
};

class Circle : public Figure {
public:
    double r;

    Circle(double r1) : r(r1) {}

    string Name() const {
        return "CIRCLE";
    }

    double Area() const {
        return pi * pow(r, 2);
    }

    double Perimeter() const {
        return 2 * pi * r;
    }
};

shared_ptr<Figure> CreateFigure(istringstream& is) {
    string kof;
    is >> kof;
    if (kof == "RECT") {
        double w, h;

        is >> w >> h;

        return make_shared<Rect>(w, h);
    }
    else if (kof == "TRIANGLE") {
        double a;
        double b;
        double c;

        is >> a >> b >> c;

        return make_shared<Triangle>(a, b, c);
    }
    else {
        double r;

        is >> r;

        return make_shared<Circle>(r);
    }
}