My C++ solution for HackerRank's "Making Candies" problem, reproduced below, is as optimized as I can make it and appears similar to what others say are optimal solutions. However, six of the test cases still fail due to timing out. I would be interested to know if there are any significant opportunities to optimize my code that I missed.
I'm guessing that I'm either missing some way to simplify the computation (perhaps part of it can be precomputed and stored in a lookup table?), or there's some way to compute the answer without using a loop.
std::ios::sync_with_stdio(false);
long m, w, p, n;
std::cin >> m >> w >> p >> n;
for (long candies = 0, passes = 0, total = LONG_MAX; ; ++passes) {
const auto production = __int128{m} * w;
const long goal = n - candies;
const long passes_needed = goal/production + !!(goal%production);
const long subtotal = passes + passes_needed;
if (passes_needed <= 2) {
std::cout << subtotal;
return 0;
}
if (total < subtotal) {
std::cout << total;
return 0;
}
total = subtotal;
candies += production;
if (candies >= p) {
const auto d = std::div(candies, p);
long budget = d.quot; candies = d.rem;
const long diff = w - m;
if (diff < 0) {
const long w_hired = std::min(budget, -diff);
budget -= w_hired;
w += w_hired;
} else if (diff > 0) {
const long m_purchased = std::min(budget, diff);
budget -= m_purchased;
m += m_purchased;
}
const long half = budget >> 1;
m += half + (budget & 1);
w += half;
}
}
__int128
compiler intrinsic to do a multiplication, but then added the result to a long. What actually happens when your algorithm fails on those 6 test?s \$\endgroup\$production
tocandies
, because ifproduction
is too large to fit in along
then it must be the case thatpasses_needed <= 2
. \$\endgroup\$