Bouncy Numbers
A positive integer is increasing if its digits form a non-decreasing sequence from left to right, decreasing if they form a non-increasing sequence, and bouncy if it is neither. Find the least posi...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, \(134468\).
Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, \(66420\).
We shall call a positive integer that is neither increasing nor decreasing a "bouncy" number; for example, \(155349\).
Clearly there cannot be any bouncy numbers below one-hundred, but just over half of the numbers below one-thousand (\(525\)) are bouncy. In fact, the least number for which the proportion of bouncy numbers first reaches \(50\%\) is \(538\).
Surprisingly, bouncy numbers become more and more common and by the time we reach \(21780\) the proportion of bouncy numbers is equal to \(90\%\).
Find the least number for which the proportion of bouncy numbers is exactly \(99\%\).
Problem 112: Bouncy Numbers
Mathematical Development
Definition 1. Let be a positive integer with decimal representation (left to right). We say is increasing if for all , decreasing if for all , and bouncy if it is neither increasing nor decreasing.
Theorem 1 (Small numbers are non-bouncy). Every positive integer is non-bouncy.
Proof. A single-digit number () has a digit sequence of length 1, which vacuously satisfies both the non-decreasing and non-increasing conditions. A two-digit number with satisfies either or , since any two integers are totally ordered. In the first case is increasing; in the second, is decreasing (in fact, strictly so). Hence no number below 100 is bouncy.
Theorem 2 (Bouncy density approaches 1). Let denote the number of bouncy integers in . Then as .
Proof. The count of non-bouncy (increasing or decreasing) positive integers with at most digits is a polynomial in of degree at most 10 (see Problem 113, where the exact formula is ). The total count of positive integers with at most digits is . Since polynomial growth is dominated by exponential growth, the fraction of non-bouncy numbers tends to 0, and consequently .
Lemma 1 (Divisibility constraint). If , then .
Proof. The equation is equivalent to , i.e., . Since is a positive integer (it counts the non-bouncy numbers up to ), it follows that .
Theorem 3 (Existence and computability). There exists a least with , and a sequential scan over all positive integers finds it in finite time.
Proof. By Theorem 2, eventually exceeds any constant less than 1, including . At , (Theorem 1), so . By Lemma 1, the target must be a multiple of 100. As increases, the non-bouncy count grows subexponentially while grows linearly, so a crossing must occur. A sequential scan checks every integer, maintains an exact count, and cannot miss the first qualifying .
Editorial
We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.
Pseudocode
bouncy_count = 0
for n = 1, 2, 3, ...:
If IsBouncy(n) then
bouncy_count += 1
If 100 * bouncy_count == 99 * n then
Return n
digits = decimal_digits(n)
has_increase = false
has_decrease = false
For i from 1 to len(digits) - 1:
if digits[i] > digits[i-1]: has_increase = true
if digits[i] < digits[i-1]: has_decrease = true
Return has_increase and has_decrease
Complexity Analysis
- Time. where is the answer. Each number requires work for digit extraction and comparison. The total work is .
- Space. for storing the digit representation of the current number.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
bool is_bouncy(int n) {
int prev = n % 10;
n /= 10;
bool inc = true, dec = true;
while (n > 0) {
int d = n % 10;
if (d > prev) inc = false;
if (d < prev) dec = false;
prev = d;
n /= 10;
}
return !inc && !dec;
}
int main() {
int bouncy = 0;
for (int n = 1;; n++) {
if (is_bouncy(n)) bouncy++;
if (100 * bouncy == 99 * n) {
cout << n << endl;
return 0;
}
}
}
def is_bouncy(n):
digits = []
while n > 0:
digits.append(n % 10)
n //= 10
digits.reverse()
inc = all(digits[i] <= digits[i + 1] for i in range(len(digits) - 1))
dec = all(digits[i] >= digits[i + 1] for i in range(len(digits) - 1))
return not inc and not dec
def solve():
bouncy = 0
n = 0
while True:
n += 1
if is_bouncy(n):
bouncy += 1
if 100 * bouncy == 99 * n:
print(n)
return
solve()