Prompt
Write a program to calculate the percentage of numbers in a given range that contain the digit 7. Your program should be able to ...
For further actions, you may consider blocking this person and/or reporting abuse
Using Rust:
We iterate until 19 digits, we will get an overflow for
i64
.Output:
Explanation for the math behind the current solution can be found here: flyingcoloursmaths.co.uk/percentag...
Generalized for any number:
Then it only returns an approximation for numbers that aren't powers of ten, though.
Without going the brute-force route (checking every number from
0..n
), is there some way of getting a more accurate estimate, or even an exact answer (well, as exact as you can get with floating point)? 🤔Can't you simply directly compute the percentage? I.e.
Think so too, since a number contains no seven iff all of its digits contain no seven, so the amount of numbers without sevens is the amount of numbers with the remaining nine digits:
$percentage=\frac{#noseven}{#total}=9^n/10^n=0.9^n$
By the way, you can write LaTeX on Dev using
{% katex %} {% endkatex %}
(You need to double-escape#
's though)You are right, it can be simplified as you pointed out. Thank you :)
Done!
GitHub file
Using Perl
My example is not as elegant as the Rust example from @ervin, as mine is a simple brute force version and has no intelligence of the math involved - and I felt that using the link he provided that showed a smart algorithm would be nothing more than really using a Perl version of his work. So points should go to him.
I include this only as an example of Perl in case anyone were interested. For brevity there is almost no error handling and no comments. It is memory efficient but not CPU efficient. Once you get up to around ten million, it becomes very inefficient:
and the output, showing the time taken for ten million is a little over 2 seconds on my 10 year old T420 Thinkpad. Anything higher and it will start to be real slow:
I took this chance to further mess around with BigInt in zig and ended up with this:
I couldn't be bothered to figure out calculating a percentage, but that's just adding a
.
after the second digit and a%
sign at the end, so who cares.*Here's my results:
* Since every range of
n
numbers has at least the range7*(n-1) to 8*(n-1)-1
, which is exactlyn-1
numbers long, for every input range there will be at least 10% sevens, and for obvious reasons there can't be 100%, so we always end up with a two-digit percentage. Since the range is always a power of 10 in length, the percentage is just the number of sevens with a decimal point added.Except the first one is 10% not 1%
Yes, without that 10%, turning the number into a percentage would have been a really simple string operation, but since
1
is single digit, you can't add a dot after the second digit without, well, first adding a second digit (a zero, of course) so that would require a bunch of extra logic that I didn't want to bother with.(also ngl I haven't used strings in zig enough to know how to do that, and didn't want to look it all up when I already had to look up so much of the bigint stuff)
Due to the limitations of stack size, my true genius is limited to 10000, but I'm sure you get the idea.
Using Java :D
Output:
My take using F#.
Another Rust solution:
Uses a fairly simple recursive approach that could probably be optimized. It uses the fact that the numbers 1xxx, 2xxx, 3xxx all contain the same number of 7s in them, so we can just multiply by the leading digit to get the answer.
This article provides an engaging and thought-provoking exercise for developers looking to hone their problem-solving and algorithmic skills. The problem is well-defined and encourages readers to think creatively to find an efficient solution.