#include #include using namespace std; ifstream input_stream; ofstream output_stream; bool checkAscending(string numStr) { char highestDigit = numStr[0]; for (uint8_t i = 1; i < numStr.length(); i++) { if (numStr[i] < highestDigit) { return false; } highestDigit = numStr[i]; } return true; } uint64_t n_choose_m(uint8_t n, uint8_t m) { if (m > n) { return 0; } if (m * 2 > n) { m = n - m; } if (m == 0) { return 1; } uint64_t res = n; for (int i = 2; i <= m; i++) { res *= n - i + 1; res /= i; } return res; } uint64_t pos_combinations(uint8_t pos) { /** pos starts at 0 from right end of number 10^pos <> 10^pos-1 */ if (pos == 0) { return 0; } else { return n_choose_m(8 + pos, pos); } } uint64_t following_combinations(uint8_t first_num, uint8_t pos) { /** 10^pos+1 <> first_num * 10^pos available = 10 - (first_num - 1) + allowed_repeats (pos) */ return n_choose_m(10 - first_num + pos, pos + 1); } uint64_t preceeding_combinations(uint8_t first_num, uint8_t pos) { /** first_num * 10^pos <> 10^pos */ return pos_combinations(pos + 1) - following_combinations(first_num, pos); } uint64_t find_ascending(string start, string end) { uint64_t result = 0; const uint8_t end_len = end.length(); if (end_len == 1) { result += stoi(end) - stoi(start) + 1; } else if (start == "1") { char highest_digit = '1'; bool sequence_integrity = true; // Run this loop until a digit lower than the others is encountered uint8_t i; for (i = 0; i < end_len - 1; i++) { uint8_t pos = end_len - i - 1; result += pos_combinations(pos); if (end[i] > highest_digit) { result += preceeding_combinations(end[i] - '0', pos) - preceeding_combinations(highest_digit - '0', pos); highest_digit = end[i]; } else if (end[i] < highest_digit) { sequence_integrity = false; break; } } i++; for (i; i < end_len - 1; i++) { uint8_t pos = end_len - i - 1; result += pos_combinations(pos); } if (sequence_integrity && end[end_len - 1] >= highest_digit) { result += end[end_len - 1] - highest_digit + 1; } } else { result += find_ascending("1", end) - find_ascending("1", start); if (checkAscending(start)) { result += 1; } } return result; } int main() { input_stream.open("input.txt"); output_stream.open("output.txt"); string A; string B; input_stream >> A; input_stream >> B; cout << find_ascending(A, B) << endl; input_stream.close(); output_stream.close(); return 0; }