#include <iostream>
#include <vector>
#include <memory>
using ohm = float;
using namespace std;
class Circuit
{
public:
virtual ohm get_resistance() const = 0;
virtual vector<string> to_string() const = 0;
};
using PCircuit = shared_ptr<Circuit>;
ostream &operator<<(ostream &os, const Circuit &circuit)
{
for (auto line : circuit.to_string())
os << line << "\n";
return os;
}
class Series : public Circuit
{
private:
vector<PCircuit> circuits;
public:
Series(initializer_list<PCircuit> circuits) : circuits(circuits) {}
ohm get_resistance() const
{
ohm resistance = 0;
for (auto pcircuit : circuits)
resistance += pcircuit->get_resistance();
return resistance;
}
vector<string> to_string() const
{
vector<string> lines = {"→ [" + std::to_string(circuits.size()) + "]"};
for (auto subcircuit : circuits)
for (auto line : subcircuit->to_string())
lines.push_back(" " + line);
return lines;
}
};
class Parallel : public Circuit
{
private:
vector<PCircuit> circuits;
public:
Parallel(initializer_list<PCircuit> circuits) : circuits(circuits) {}
ohm get_resistance() const
{
ohm invResistance = 0;
for (auto pcircuit : circuits)
invResistance += 1 / pcircuit->get_resistance();
return 1 / invResistance;
}
vector<string> to_string() const
{
vector<string> lines = {"⊢ [" + std::to_string(circuits.size()) + "]"};
for (auto subcircuit : circuits)
for (auto line : subcircuit->to_string())
lines.push_back(" " + line);
return lines;
}
};
class Resistor : public Circuit
{
private:
ohm value;
public:
Resistor(ohm value) : value(value) {}
ohm get_resistance() const
{
return value;
}
vector<string> to_string() const
{
return vector<string>{std::to_string(value) + " Ω"};
}
};
int main()
{
Series example = {
PCircuit(new Resistor(500)),
PCircuit(new Resistor(600)),
PCircuit(new Parallel({PCircuit(new Series({PCircuit(new Resistor(200)),
PCircuit(new Resistor(100))})),
PCircuit(new Series({PCircuit(new Resistor(4))}))})),
PCircuit(new Resistor(300))};
cout << example.get_resistance() << endl;
cout << example << endl;
return 0;
}