#include <iostream>
class Wheel {
private:
int resource = 0;
public:
Wheel(int resource) {
this->resource = resource;
}
void use(int time) {
this->resource -= time;
}
int getResource() {
return resource;
}
};
#define CAR_WHEELS 4
class Car {
private:
Wheel* wheels[CAR_WHEELS];
Wheel* trunk;
public:
Car() {
for(int i = 0; i < CAR_WHEELS; i++) {
wheels[i] = nullptr;
}
trunk = nullptr;
}
void setWheel(Wheel* wheel, int place) {
if (place > CAR_WHEELS - 1 || place < 0) return;
wheels[place] = wheel;
}
void setTrunk(Wheel* wheel) {
this->trunk = wheel;
}
void go(int time) {
for(int i = 0; i < CAR_WHEELS; i++) {
wheels[i]->use(time);
}
std::cout << "go " << time << std::endl;
this->info();
}
void replaceWheelFromTrunk(int place) {
if (place > CAR_WHEELS - 1 || place < 0) return;
Wheel* temp = wheels[place];
wheels[place] = trunk;
trunk = temp;
std::cout << "trunk <-> place " << place << std::endl;
this->info();
}
void info() {
for(int i = 0; i < CAR_WHEELS; i++) {
std::cout << "P" << i << ": " << wheels[i]->getResource() << " ";
}
std::cout << "T" << ": " << trunk->getResource() << " " << std::endl;
std::cout << std::endl;
}
};
class CarBuilder {
public:
Car* build() {
Car* car = new Car();
Wheel* wheel;
int resource = 100;
for(int i = 0; i < 4; i++) {
wheel = new Wheel(resource);
car->setWheel(wheel, i);
}
wheel = new Wheel(resource);
car->setTrunk(wheel);
return car;
}
};
class DriverStrategy {
public:
void execute(Car* car) {
const int STEPS = 4;
int steps[STEPS][2] = {
{25, 0},
{25, 1},
{25, 2},
{25, 3},
};
for(int i = 0; i < STEPS; i++) {
car->go(steps[i][0]);
car->replaceWheelFromTrunk(steps[i][1]);
}
car->go(25);
}
};
class Driver {
private:
Car* car;
DriverStrategy* strategy;
//Road road;
public:
void go() {
strategy->execute(this->car);
}
void setStrategy(DriverStrategy* strategy) {
this->strategy = strategy;
}
void jumpInCar(Car* car) {
this->car = car;
}
};
int main(int argc, char* argv[]) {
CarBuilder builder;
Car* mycar = builder.build();
Driver driver;
DriverStrategy* strategy = new DriverStrategy();
driver.setStrategy(strategy);
driver.jumpInCar(mycar);
mycar->info();
driver.go();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKY2xhc3MgV2hlZWwgewpwcml2YXRlOgogICAgaW50IHJlc291cmNlID0gMDsKCnB1YmxpYzoKICAgIFdoZWVsKGludCByZXNvdXJjZSkgewogICAgICAgIHRoaXMtPnJlc291cmNlID0gcmVzb3VyY2U7ICAgIAogICAgfQoKICAgIHZvaWQgdXNlKGludCB0aW1lKSB7CiAgICAgICAgdGhpcy0+cmVzb3VyY2UgLT0gdGltZTsKICAgIH0KCiAgICBpbnQgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgfQp9OwoKCiNkZWZpbmUgQ0FSX1dIRUVMUyA0CgpjbGFzcyBDYXIgewpwcml2YXRlOgogICAgV2hlZWwqIHdoZWVsc1tDQVJfV0hFRUxTXTsKICAgIFdoZWVsKiB0cnVuazsKCnB1YmxpYzoKICAgIENhcigpIHsKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgQ0FSX1dIRUVMUzsgaSsrKSB7CiAgICAgICAgICAgIHdoZWVsc1tpXSA9IG51bGxwdHI7CiAgICAgICAgfQogICAgICAgIHRydW5rID0gbnVsbHB0cjsKICAgIH0KCiAgICB2b2lkIHNldFdoZWVsKFdoZWVsKiB3aGVlbCwgaW50IHBsYWNlKSB7CiAgICAgICAgaWYgKHBsYWNlID4gQ0FSX1dIRUVMUyAtIDEgfHwgcGxhY2UgPCAwKSByZXR1cm47CiAgICAgICAgd2hlZWxzW3BsYWNlXSA9IHdoZWVsOwogICAgfQoKICAgIHZvaWQgc2V0VHJ1bmsoV2hlZWwqIHdoZWVsKSB7CiAgICAgICAgdGhpcy0+dHJ1bmsgPSB3aGVlbDsKICAgIH0KCiAgICB2b2lkIGdvKGludCB0aW1lKSB7CiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IENBUl9XSEVFTFM7IGkrKykgewogICAgICAgICAgICB3aGVlbHNbaV0tPnVzZSh0aW1lKTsKICAgICAgICB9CgogICAgICAgIHN0ZDo6Y291dCA8PCAiZ28gIiA8PCB0aW1lIDw8IHN0ZDo6ZW5kbDsKICAgICAgICB0aGlzLT5pbmZvKCk7CiAgICB9CgogICAgdm9pZCByZXBsYWNlV2hlZWxGcm9tVHJ1bmsoaW50IHBsYWNlKSB7CiAgICAgICAgaWYgKHBsYWNlID4gQ0FSX1dIRUVMUyAtIDEgfHwgcGxhY2UgPCAwKSByZXR1cm47CiAgICAgICAgV2hlZWwqIHRlbXAgPSB3aGVlbHNbcGxhY2VdOwogICAgICAgIHdoZWVsc1twbGFjZV0gPSB0cnVuazsKICAgICAgICB0cnVuayA9IHRlbXA7CgogICAgICAgIHN0ZDo6Y291dCA8PCAidHJ1bmsgPC0+IHBsYWNlICIgPDwgcGxhY2UgPDwgc3RkOjplbmRsOwogICAgICAgIHRoaXMtPmluZm8oKTsKICAgIH0KCiAgICB2b2lkIGluZm8oKSB7CiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IENBUl9XSEVFTFM7IGkrKykgewogICAgICAgICAgICBzdGQ6OmNvdXQgPDwgIlAiIDw8IGkgPDwgIjogIiA8PCB3aGVlbHNbaV0tPmdldFJlc291cmNlKCkgPDwgIiAiOwogICAgICAgIH0KCiAgICAgICAgc3RkOjpjb3V0IDw8ICJUIiA8PCAiOiAiIDw8IHRydW5rLT5nZXRSZXNvdXJjZSgpIDw8ICIgIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICAgIH0KCn07CgpjbGFzcyBDYXJCdWlsZGVyIHsKcHVibGljOgogICAgQ2FyKiBidWlsZCgpIHsKICAgICAgICBDYXIqIGNhciA9IG5ldyBDYXIoKTsKICAgICAgICBXaGVlbCogd2hlZWw7CiAgICAgICAgaW50IHJlc291cmNlID0gMTAwOwoKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgIHdoZWVsID0gbmV3IFdoZWVsKHJlc291cmNlKTsKICAgICAgICAgICAgY2FyLT5zZXRXaGVlbCh3aGVlbCwgaSk7CiAgICAgICAgfQoKICAgICAgICB3aGVlbCA9IG5ldyBXaGVlbChyZXNvdXJjZSk7CiAgICAgICAgY2FyLT5zZXRUcnVuayh3aGVlbCk7CgogICAgICAgIHJldHVybiBjYXI7CiAgICB9Cn07CgpjbGFzcyBEcml2ZXJTdHJhdGVneSB7CnB1YmxpYzoKICAgIHZvaWQgZXhlY3V0ZShDYXIqIGNhcikgewoKICAgICAgICBjb25zdCBpbnQgU1RFUFMgPSA0OyAgICAKCiAgICAgICAgaW50IHN0ZXBzW1NURVBTXVsyXSA9IHsKICAgICAgICAgICAgezI1LCAwfSwgCiAgICAgICAgICAgIHsyNSwgMX0sIAogICAgICAgICAgICB7MjUsIDJ9LCAKICAgICAgICAgICAgezI1LCAzfSwgCiAgICAgICAgfTsKCiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IFNURVBTOyBpKyspIHsKICAgICAgICAgICAgY2FyLT5nbyhzdGVwc1tpXVswXSk7CiAgICAgICAgICAgIGNhci0+cmVwbGFjZVdoZWVsRnJvbVRydW5rKHN0ZXBzW2ldWzFdKTsKICAgICAgICB9CgogICAgICAgIGNhci0+Z28oMjUpOwogICAgfQp9OwoKY2xhc3MgRHJpdmVyIHsKcHJpdmF0ZToKICAgIENhciogY2FyOwogICAgRHJpdmVyU3RyYXRlZ3kqIHN0cmF0ZWd5OwogICAgLy9Sb2FkIHJvYWQ7CgpwdWJsaWM6IAogICAgdm9pZCBnbygpIHsKICAgICAgICBzdHJhdGVneS0+ZXhlY3V0ZSh0aGlzLT5jYXIpOwogICAgfQoKICAgIHZvaWQgc2V0U3RyYXRlZ3koRHJpdmVyU3RyYXRlZ3kqIHN0cmF0ZWd5KSB7CiAgICAgICAgdGhpcy0+c3RyYXRlZ3kgPSBzdHJhdGVneTsKICAgIH0KCiAgICB2b2lkIGp1bXBJbkNhcihDYXIqIGNhcikgewogICAgICAgIHRoaXMtPmNhciA9IGNhcjsKICAgIH0KfTsKCgppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CiAgICBDYXJCdWlsZGVyIGJ1aWxkZXI7CiAgICBDYXIqIG15Y2FyID0gYnVpbGRlci5idWlsZCgpOwoKICAgIERyaXZlciBkcml2ZXI7CiAgICBEcml2ZXJTdHJhdGVneSogc3RyYXRlZ3kgPSBuZXcgRHJpdmVyU3RyYXRlZ3koKTsKICAgIGRyaXZlci5zZXRTdHJhdGVneShzdHJhdGVneSk7CiAgICBkcml2ZXIuanVtcEluQ2FyKG15Y2FyKTsKCiAgICBteWNhci0+aW5mbygpOwogICAgZHJpdmVyLmdvKCk7CgogICAgcmV0dXJuIDA7Cn0K