Skip to content

Instantly share code, notes, and snippets.

@ennorehling
Last active March 26, 2024 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ennorehling/5dc3251c1cec60c8998bd1ff40f527be to your computer and use it in GitHub Desktop.
Save ennorehling/5dc3251c1cec60c8998bd1ff40f527be to your computer and use it in GitHub Desktop.
/**
* `n` persons with skill `sn` are merged into `add` persons with skill `sv`
*/
int merge_skill(const skill* sv, const skill* sn, skill* result, int n, int add)
{
int total = add + n;
/* number of person-weeks the units have already studied: */
int days, weeks = weeks_from_level(sn ? sn->level : 0) * n
+ weeks_from_level(sv ? sv->level : 0) * add;
/* level that combined unit should be at: */
int level = level_from_weeks(weeks, total);
/* minimum new level, based only on weeks spent towards current levels: */
result->level = level;
/* average time to the next level: */
result->days = (level + 1) * SKILL_DAYS_PER_WEEK;
/* add any remaining weeks to the already studied ones and convert to days: */
weeks -= weeks_from_level(level) * total;
days = weeks * SKILL_DAYS_PER_WEEK;
/* adjusted by how much we already studied: */
if (sv) days += days_studied(sv) * add;
if (sn) days += days_studied(sn) * n;
if (days < 0) {
result->days -= days / total;
}
else if (days >= total) {
days = result->days - days / total;
while (days < 0) {
++result->level;
days += result->level * SKILL_DAYS_PER_WEEK;
}
result->days = days;
}
return result->level;
}
/**
* `n` persons with skill `sn` are merged into `add` persons with skill `sv`
*/
int merge_skill(const skill* sv, const skill* sn, skill* result, int n, int add)
{
int total = add + n;
/* number of person-weeks the units have already studied: */
int days, weeks = weeks_from_level(sn ? sn->level : 0) * n
+ weeks_from_level(sv ? sv->level : 0) * add;
/* level that combined unit should be at: */
int level = level_from_weeks(weeks, total);
/* minimum new level, based only on weeks spent towards current levels: */
result->level = level;
/* average time to the next level: */
result->days = (level + 1) * SKILL_DAYS_PER_WEEK;
/* add any remaining weeks to the already studied ones and convert to days: */
weeks -= weeks_from_level(level) * total;
days = weeks * SKILL_DAYS_PER_WEEK;
/* adjusted by how much we already studied: */
if (sv) days += days_studied(sv) * add;
if (sn) days += days_studied(sn) * n;
if (days < 0) {
result->days -= days / total;
}
else if (days >= total) {
int pdays = total * result->days - days;
while (pdays < 0) {
++result->level;
pdays += total * result->level * SKILL_DAYS_PER_WEEK;
}
result->days = (pdays + total - 1 ) / total;
}
return result->level;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment