Skip to content

Instantly share code, notes, and snippets.

@maestroprog
Created July 22, 2018 19:52
Show Gist options
  • Save maestroprog/39f8c7ba39e057e43e72af9f2416d638 to your computer and use it in GitHub Desktop.
Save maestroprog/39f8c7ba39e057e43e72af9f2416d638 to your computer and use it in GitHub Desktop.
birds calc
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <bits/stdc++.h>
#include <unistd.h>
using namespace std;
struct BirdData {
int price;
double dailyEarn;
};
struct EarnForPeriod {
double earn;
double money;
double dailyEarn;
std::vector<string> active;
};
BirdData birds[6];
int maxDays = 0;
EarnForPeriod getEarnForPeriod(int day, double dailyEarn, double money, int level = 1);
int main(int argc, char *argv[]) {
maxDays = stoi(argv[1]);
int money = stoi(argv[2]);
birds[0] = {1000, 23.352 / 2};
birds[1] = {500, 11.16 / 2};
birds[2] = {100, 2.16 / 2};
birds[3] = {50, 0.816 / 2};
birds[4] = {10, 0.096 / 2};
birds[5] = {3, 0.024 / 2};
int dailyEarn = 0;
EarnForPeriod period = getEarnForPeriod(1, dailyEarn, money);
std::cout << "Earn = " << (period.earn) << std::endl;
std::cout << "Money = " << (period.money) << std::endl;
std::cout << "Daily earn = " << (period.dailyEarn) << std::endl;
for (const auto &chars: period.active) {
std::cout << chars << std::endl;
}
return 0;
}
EarnForPeriod getEarnForPeriod(int day, double dailyEarn, double money, int level) {
std::vector<string> active;
int wait = 0; // что ждёт купить
double earn = 0;
for (int i = day; i <= maxDays && level < 7; i++) {
if (level == 1) {
std::cout << "Day " << i << std::endl;
} else {//if (level == i) {
// std::cout << std::string(static_cast<unsigned long>(level), ' ') << " Day " << i << " in level " << level
// << std::endl;
// usleep(10000);
}
bool buy;
if (wait <= 0) { // если еще ничего не ждет, то определяется с тем чего ждать
int currentDay = i;
double currentMoney = money;
int calculatedPrice = 0;
double calculatedEarn = 0;
if (currentDay < maxDays) {
int remainingDays = maxDays - currentDay;
double earnedMoney =
currentMoney + dailyEarn * remainingDays;
for (BirdData &bird : birds) {
if (earnedMoney >= bird.price) {
// if (bird.price < 100) {
// continue;
// }
int remainingForBird;
if (dailyEarn > 0) {
remainingForBird = std::max(0, (int) (std::ceil(bird.price - currentMoney) / dailyEarn));
} else {
remainingForBird = 0;
}
double earnByDays = dailyEarn * remainingForBird;
auto countBirds = (int) std::floor((earnByDays + currentMoney) / bird.price);
if (countBirds <= 0) {
continue;
}
EarnForPeriod result = getEarnForPeriod(
currentDay + remainingForBird,
dailyEarn + bird.dailyEarn * countBirds,
earnByDays + currentMoney - bird.price * countBirds,
level + 1
);
double d = earnByDays + result.earn;
if (d > calculatedEarn) {
calculatedPrice = bird.price;
calculatedEarn = d;
if (remainingForBird <= 0) {
break;
}
}
}
}
}
if (calculatedPrice > 0) {
wait = calculatedPrice;
}
}
do {
buy = false;
if (wait < 0) {
throw "Cannot wait nothing.";
}
for (BirdData &bird : birds) {
if (bird.price == wait && money >= bird.price) {
active.emplace_back(
std::string("day ") + std::to_string(i)
+ ", money " + std::to_string(money)
+ ", buy bird " + std::to_string(bird.price)
+ ", earn " + std::to_string(earn)
+ ", daily earn " + std::to_string(dailyEarn)
);
money -= bird.price;
dailyEarn += bird.dailyEarn;
buy = true;
break;
} else if (wait == bird.price) {
wait = 0;
break;
}
}
} while (buy);
earn += dailyEarn;
money += dailyEarn;
}
return {earn, money, dailyEarn, active};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment