Lucky Numbers

Last Updated : 17 Oct, 2026

Given an integer n, determine if it is a Lucky Number.

Lucky numbers are identified using a elimination process on the infinite sequence of natural numbers (1, 2, 3, 4, ...):
   1. Remove every 2nd number from the sequence.
   2. From the remaining sequence, remove every 3rd number.
   3. From the remaining sequence, remove every 4th number, and so on...

This continues indefinitely. Return true if n survives the elimination process (is a lucky number). Otherwise, return false.

Input: n = 5
Output: false
Explanation: 5 is not a lucky number as it gets deleted in the second iteration.

Input: n = 19
Output: true
Explanation: 19 is a lucky number because it does not get deleted throughout the process.

Try It Yourself
redirect icon

[Naive Approach] Simulate Elimination - O(n log n) and O(n)

We explicitly simulate the elimination process by generating an array of integers from 1 to n.

In the kth step (starting from 2), we remove every k-th element from our list until the step size k exceeds the remaining length of the list, and then check if n survived.

C++
#include <bits/stdc++.h>
using namespace std;

bool isLucky(int n)
{

    // Generate the initial sequence from 1 to n
    vector<int> nums(n);
    for (int i = 0; i < n; ++i)
    {
        nums[i] = i + 1;
    }

    int k = 2;

    // Continue eliminating while the step size is valid
    while (k <= nums.size())
    {

        // Use a temporary vector to store surviving numbers
        vector<int> next_nums;

        for (int i = 0; i < nums.size(); ++i)
        {

            // Keep the number if its 1-based position
            // is NOT a multiple of k
            if ((i + 1) % k != 0)
            {
                next_nums.push_back(nums[i]);
            }
        }

        // Update our main sequence to the newly filtered one
        nums = next_nums;
        k++;
    }

    // Check if 'n' survived by searching for it 
    // in the remaining numbers
    return find(nums.begin(), nums.end(), n) != nums.end();
}

int main()
{
    int x = 5;

    if (isLucky(x))
        cout << "true" << endl;
    else
        cout << "false" << endl;
}
Java
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static boolean isLucky(int n)
    {

        // Generate the initial sequence from 1 to n
        List<Integer> nums = new ArrayList<>();
        for (int i = 1; i <= n; ++i) {
            nums.add(i);
        }

        int k = 2;

        // Continue eliminating while the step size is valid
        while (k <= nums.size()) {

            // Use a temporary list to store surviving
            // numbers
            List<Integer> next_nums = new ArrayList<>();
            for (int i = 0; i < nums.size(); ++i) {

                // Keep the number if its 1-based position
                // is NOT a multiple of k
                if ((i + 1) % k != 0) {
                    next_nums.add(nums.get(i));
                }
            }

            // Update our main sequence to the newly
            // filtered one
            nums = next_nums;
            k++;
        }

        // Check if 'n' survived by searching for it in the
        // remaining numbers
        return nums.contains(n);
    }

    public static void main(String[] args)
    {
        int x = 5;

        if (isLucky(x)) {
            System.out.println("true");
        }
        else {
            System.out.println("false");
        }
    }
}
Python
def isLucky(n):
    # Generate the initial sequence from 1 to n
    nums = list(range(1, n + 1))

    k = 2

    # Continue eliminating while the step size is valid
    while k <= len(nums):

        # Use a temporary list to store surviving numbers
        next_nums = []
        for i in range(len(nums)):

            # Keep the number if its 1-based position
            # is NOT a multiple of k
            if (i + 1) % k != 0:
                next_nums.append(nums[i])

        # Update our main sequence to the newly filtered one
        nums = next_nums
        k += 1

    # Check if 'n' survived by searching for it in the remaining numbers
    return n in nums

if __name__ == "__main__":
    x = 5
    
    if isLucky(x):
        print("true")
    else:
        print("false")
C#
using System;

class GfG
{
    static bool isLucky(int n)
    {
        int[] nums = new int[n];

        // Create the initial sequence
        for (int i = 0; i < n; i++)
            nums[i] = i + 1;

        int size = n;
        int k = 2;

        // Remove every k-th element
        while (k <= size)
        {
            int write = 0;

            for (int i = 0; i < size; i++)
            {
                if ((i + 1) % k != 0)
                    nums[write++] = nums[i];
            }

            size = write;
            k++;
        }

        // Check whether n survived
        for (int i = 0; i < size; i++)
        {
            if (nums[i] == n)
                return true;
        }

        return false;
    }

    static void Main()
    {
        int x = 5;

        if (isLucky(x))
        {
            Console.WriteLine("true");
        }
        else
        {
            Console.WriteLine("false");
        }
    }
}
JavaScript
function isLucky(n)
{
    // Generate the initial sequence from 1 to n
    let nums = Array.from({length : n}, (_, i) => i + 1);

    let k = 2;

    // Continue eliminating while the step size is valid
    while (k <= nums.length) {

        // Use a temporary array to store surviving numbers
        let next_nums = [];
        for (let i = 0; i < nums.length; ++i) {

            // Keep the number if its 1-based position
            // is NOT a multiple of k
            if ((i + 1) % k != 0) {
                next_nums.push(nums[i]);
            }
        }

        // Update our main sequence to the newly filtered
        // one
        nums = next_nums;
        k++;
    }

    // Check if 'n' survived by searching for it in the
    // remaining numbers
    return nums.includes(n);
}

// Driver Code
let x = 5;

if (isLucky(x)) {
    console.log("true");
}
else {
    console.log("false");
}

Output
false

[Expected Approach] Position Tracking - O(sqrt(n)) Time and O(1) Space

We only track the current position of n, which is initially n itself.

At each step k,

  • If the position is perfectly divisible by k, n is the element being removed.
  • Otherwise, its new position shifts leftward by the number of elements removed before it (n - n / k).

Let's understand with an example:
Say, n=13
We have: Initial position: n, i.e. 13 itself.  Sequence : 1,2,3,4,5,6,7,8,9,10,11,12,13

  • k = 2 : Removing every second elements. So now the position of 13 will be : n-n/2 = 13-6=7. Sequence : 1,3,5,7,9,11,13.
  • k = 3 : Removing n/3 items. Note that n now is n=7. So position of 13 : n-n/3 = 7-7/3 = 7-2 = 5. Sequence = 1,3,7,9,13.
  • k = 4 : So next it will be : n-n/4 = 5-5/4 = 4. Sequence = 1,3,7,13.
  • k = 5 : Since position of 13 is 4 only, so it will be saved.

Hence return true.

C++
#include <bits/stdc++.h>
using namespace std;

bool isLucky(int n)
{
    int counter = 2;

    // Loop continues as long as counter <= n
    while (counter <= n) {
        // If the position is a multiple of counter, it's eliminated
        if (n % counter == 0)
            return false;

        // Calculate next position of input no
        n = n - n / counter;

        // Increment the step size
        counter++;
    }

    // If we break out of the loop, the number survived
    return true;
}

int main()
{
    int x = 5;

    // Function call
    if (isLucky(x))
        cout << "true" << endl;
    else
        cout << "false" << endl;

    return 0;
}
Java
public class Main {
    public static boolean isLucky(int n) {
        int counter = 2;
        
        // Loop continues as long as counter <= n
        while (counter <= n) {
            
            // If the position is a multiple of counter, it's eliminated
            if (n % counter == 0)
                return false;
                
            // Calculate next position of input no
            n = n - n / counter;
            
            // Increment the step size
            counter++;
        }
        
        // If we break out of the loop, the number survived
        return true;
    }

    public static void main(String[] args) {
        int x = 5;
        // Function call
        if (isLucky(x))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
def isLucky(n):
    counter = 2
    
    # Loop continues as long as counter <= n
    while counter <= n:
        
        # If the position is a multiple of counter, it's eliminated
        if n % counter == 0:
            return False
            
        # Calculate next position of input no
        n = n - n // counter
        
        # Increment the step size
        counter += 1
        
    # If we break out of the loop, the number survived
    return True

if __name__ == "__main__":
    x = 5
    if isLucky(x):
        print('true')
    else:
        print('false')
C#
using System;

public class Program
{
    public static bool isLucky(int n)
    {
        int counter = 2;
        // Loop continues as long as counter <= n
        while (counter <= n)
        {
            // If the position is a multiple of counter, it's eliminated
            if (n % counter == 0)
                return false;
                
            // Calculate next position of input no
            n = n - n / counter;
            
            // Increment the step size
            counter++;
        }
        // If we break out of the loop, the number survived
        return true;
    }

    public static void Main()
    {
        int x = 5;
        if (isLucky(x))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
function isLucky(n) {
    let counter = 2;
    
    // Loop continues as long as counter <= n
    while (counter <= n) {
        
        // If the position is a multiple of counter, it's eliminated
        if (n % counter === 0)
            return false;
            
        // Calculate next position of input no
        n = n - Math.floor(n / counter);
        
        // Increment the step size
        counter++;
    }
    
    // If we break out of the loop, the number survived
    return true;
}

// Driver Code
let x = 5;
if (isLucky(x))
    console.log('true');
else
    console.log('false');

Output
false
Comment