#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include<map>

using std::map;
using std::string;
using std::cout;
using std::cin;
using std::vector;
using std::endl;
using std::runtime_error;


class Object {
 public:
    virtual string ToString() const = 0;

    virtual ~Object() = default;
};

class Apple : public Object {
 public:
    string ToString() const override {
        return "apple!";
    }
};

class List : public Object {
 public:
    string ToString() const override {
        return "list";
    }
};

class YetAnotherId : public Object {
 public:
    string ToString() const override {
        return "yet another identifier";
    }
};

class Smth : public Object {
 public:
    explicit Smth(const std::string& class_id) {
        class_id_ = class_id;
    }

    std::string ToString() const override {
        return class_id_;
    }
 private:
    std::string class_id_;
};

map<string, Object *(*)()> registered_classes;

class Factory {
 public:
    static Object *Create(const string &class_id) {
        if (class_id == "apple") {
            return new Apple;
        } else if (class_id == "list") {
            return new List;
        } else if (class_id == "yet another identifier") {
            return new YetAnotherId;
        } else {
            if (registered_classes.count(class_id) > 0) {
                return new Smth(class_id);
            } else { throw runtime_error("not registered"); }
        }
    }

    static void Register(const string &class_id, Object *(*creator)()) {
        registered_classes[class_id] = creator;
    }
};