This would probably be the fastest in the general case (pardon the templates, just there for my sanity):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
template< unsigned P >
struct Power {
enum { value = 10 * Power< P-1 >::value };
};
template<>
struct Power<0U> {
enum { value = 1 };
};
unsigned remove_first( unsigned x ) {
if( x >= Power<5>::value ) {
if( x >= Power<7>::value ) {
if( x >= Power<9>::value ) {
return x % Power<9>::value;
} else if( x >= Power<8>::value ) {
return x % Power<8>::value;
} else {
return x % Power<7>::value;
}
} else if( x >= Power<6>::value ) {
return x % Power<6>::value;
} else {
return x % Power<5>::value;
}
} else {
if( x >= Power<3>::value ) {
if( x >= Power<4>::value ) {
return x % Power<4>::value;
} else {
return x % Power<3>::value;
}
} else if( x >= Power<1>::value ) {
if( x >= Power<2>::value ) {
return x % Power<2>::value;
} else {
return x % Power<1>::value;
}
} else {
return x;
}
}
}
|
The function will perform either 3 or 4 comparisons (for values between 10^8 and 10^9 - 1 it will be 4, for all others 3).
I suppose statistically speaking it could be made slightly faster still by flipping all the comparisons to less than, at which
point the worst case will be a much smaller range of inputs as opposed to the range 10^8...10^9-1.
But anyway, I'll file the above code under "solutions awaiting problems".
To be fair though, any numerical approach to the problem has the problem that it loses all zero digits in the number.
To get around this limitation, a string-based approach must be taken.