A friend visited for a while, so by the time I'm actually able to tackle this, it's nearly midnight. I'm wondering if I'm going to be able to catch up at all. Ideally I'd like to finish this on Christmas Eve, like last year, feeling accomplished. But I have a lot of catching up to do to be able to say that.
This is... a complicated input. Pretty difficult to parse. Both as a person, and telling a machine how to. At least.... seemingly complicated? Annoying is a better word for it. Most of it is boilerplate, with only a few small characters actually mattering.
for (int round = 0; round < MONKEY_ROUNDS; round++)
{
for (int i = 0; i < bunch.size(); i++)
while (bunch[i]->items->size() > 0)
{
Monkey* m = bunch[i];
int64_t item = m->items->at(0);
m->items->pop_front();
int numerand = (m->numerand == -1) ? item : m->numerand;
switch (m->operand)
{
case '+': item += numerand; break;
case '*': item *= numerand; break;
}
item /= 3;
int target = item % m->divTest == 0 ? m->trueTarget : m->falseTarget;
bunch[target]->items->push_back(item);
m->inspections++;
}
}
The hard part of this though... was realizing that some of the worry levels got so high, I had to use an int64_t
instead of a standard int
. Spent like half an hour on that alone.
Ahaahh, for this one, I guess worry is going to get so high that int64_t
won't be enough. It runs fast enough, I just need to manage my worry (essentially deal with extremely large numbers). There's two ways I can deal with this:
- Roll my own (basic) bigint type
- Find a library to deal with it for me
Rolling my own, I'll have to implement addition, multiplication, and modulo. Addition and Multiplication aren't too bad, but modulo... that'll be annoying. But I don't mind looking up a formula - apparently just adding up the individual digits will be enough.
...
Okay the number of digits is in the thousands, and this isn't going to run in a reasonable amount of time. I've got to get more clever. Maybe dividing by something in each step? I have a feeling that the 'divide by 3' step was a hit, I need to divide by something. Maybe by the testing modulo? Oh, the multiple of all of the divisors?
Yep! That was it. It was a small change, but big brain to actually figure that out... and maybe a lot of googling and iteration.
long long bigDiv = 1;
// In parsing
bigDiv *= m->divTest;
// In main loop
item %= bigDiv;
Three simple lines, and a long while of banging my head against my desk trying to think of it. It's late though. I should sleep, do the rest while I am more awake.