#include #include typedef uint64_t natural; const natural all_digits = 0x00000f9876543210LL; inline natural select (natural set, natural sel) { return ( set >> sel ) & 0xfLL; } inline natural remove (natural set, natural sel) { return (( set & ~((1LL << (sel + 4)) - 1)) >> 4) | ( set & ((1LL << sel ) - 1) ); } int main () { const natural max = 10000000000LL; natural last_value = 1; natural biggest_jump = 0; natural biggest_jump_value; natural biggest_jump_last; natural total = 0; printf("max %qd\n", max); natural topdigit = 0; natural set[10]; int sel[10]; for (int i = 0; i < 10; ++i) { set[i] = 0; sel[i] = 0; } natural value = 0; natural c = 0; for (; ; ++c) { int i = 0; natural pow = 1; for (; i < 10; ++i) { if (set[i] == 0) { // top digit sel[i] = 4; set[i] = all_digits; value = pow; break; } natural current = (set[i] >> sel[i]) & 0xfLL; value -= pow * current; sel[i] += 4; natural next = (set[i] >> sel[i]) & 0xfLL; if (next != 0xf) { value += pow * next; break; } pow *= 10; } if ( i == 10) break; // calculate prefix sets for (int j = i; j > 0; --j) { set[j-1] = remove(set[j], sel[j]); sel[j-1] = 0; } pow = 1; for (int j = 0; j < i; ++j) { value += pow * select(set[j], sel[j]); pow *= 10; } if (value > max) break; total = total + value; natural jump = value - last_value; if (jump > biggest_jump) { biggest_jump = jump; biggest_jump_last = last_value; biggest_jump_value = value; //~ printf("\njump %qd %qd %qd\n", jump, last_value, value); } last_value = value; } printf("\n"); printf("total %ld\n", total); printf("number of values generated %ld\n", c); printf("biggest jump %lld from %lld to %lld\n", biggest_jump, biggest_jump_last, biggest_jump_value); return 0; }