4

A Vivaldi's number is a number that can be factored by only 2, 3 and 5 ( V = 2^a * 3^b * 5^c, a, b, c = 0,1,...; also known as Hamming number). The task is to find the Nth Vivaldi number.

The algorithm isn't too bad for small inputs, but N ranges from 0 to 9999. It took 2 minutes at 2000. I wrote the code with a pretty simple algorithm, but I'm curious (hopeful) to find another way. I tried to tackle this problem mathematically with logarithms but ended up nowhere. Is an efficient way even possible when it comes to large inputs?

#include <iostream>
#include <cstdlib>
#include <ctime>


bool vivaldi(unsigned long long d) {

    while (d%2 == 0)
        d = d/2;

    while (d%3 == 0)
        d = d/3;

    while (d%5 == 0)
        d = d/5;


    if (d == 1)
        return true;

    return false;
}



int main() {

    int count = 0, N;
    unsigned long long number = 0;

    std::cin >> N;

    std::clock_t begin = clock();

    if (N < 0 || N > 9999) {
        std::fprintf(stderr, "Bad input\n");
        std::exit(EXIT_FAILURE);
    }

    while (count <= N) {

        number++;
        if (vivaldi(number))
            count++;

    }

    std::cout << number << std::endl;
    std::clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
    std::cout << "TIME: " << elapsed_secs << std::endl;
}
Will Ness
  • 62,652
  • 8
  • 86
  • 167
monolith937
  • 389
  • 3
  • 11
  • 2
    If you have a known requirement of 0 to 9999, you could simply have a lookup table (O(1)) – mnistic Nov 08 '17 at 18:48
  • @mnistic: could you clarify how I would go about that exactly ? – monolith937 Nov 08 '17 at 18:54
  • Precompute all the numbers and sort them in a table -- a one time deal. Are you allowed to do that? – mnistic Nov 08 '17 at 18:55
  • Well, the course is about algorithms. Plus I'd never been introduced to lookup tables, but that's on me. – monolith937 Nov 08 '17 at 18:57
  • 1
    Your program is wrong anyway (or doesn't match your question). You said you wanted the nth vivaldi's number, but you only check up to n. which means you don't ever get the nth number, you just get the number of vivaldi's numbers betwen 0 and n. – xyious Nov 08 '17 at 19:12
  • You could change %2 to ` & 1 == 0` : ` while (d & 1 == 0) d = d >> 1;` and see if that has an impact. – xyious Nov 08 '17 at 19:16
  • @xyious: forgot to mention, but enumeration starts from 0 – monolith937 Nov 08 '17 at 19:21
  • I've never heard of a Vivaldi number before, are you able to point me to another resource to learn about them? – AndyG Nov 08 '17 at 20:23
  • @AndyG: I don't think they're real. I guess they were called like that out of fun – monolith937 Nov 08 '17 at 20:24
  • 1
    Maybe, if you started with the formula, and proceeded with a method to put increasing variables a,b, and c in a certain order, that would give subsequent product numbers, you wouldn't have to have a ton of division operations on each Vivaldi and each in-between number. – Victor Nov 08 '17 at 20:33
  • 1
    So I've done some more research and it appears that what you're trying to compute are called [hamming numbers](https://en.wikipedia.org/wiki/Regular_number), of which a lot of intense research has been done. There is an abundance of code out there, too. – AndyG Nov 08 '17 at 20:43
  • 1
    For example, this question is nearly identical to yours: https://stackoverflow.com/q/29286845/27678 – AndyG Nov 08 '17 at 20:48
  • @AndyG: yeah, just found about it 30 seconds ago. Eh I guess this one can be closed as a duplicate. Thank you Andy – monolith937 Nov 08 '17 at 20:50
  • 1
    Lots of related StackOverflow questions https://stackoverflow.com/q/10126285/27678, and https://stackoverflow.com/q/37199032/27678 – AndyG Nov 08 '17 at 20:50
  • You don't need any of those `while` loops in `vivaldi()` ... – Mike Robinson Feb 03 '20 at 20:05
  • @MikeRobinson [yes, but...](https://stackoverflow.com/questions/4600048/nth-ugly-number/4600082#comment106193889_4600082). – Will Ness Feb 04 '20 at 08:39

0 Answers0