Find Nice Numbers: A Program to Count Divisible Digits in Range [0,1000]

In summary: I think that's pretty much it.In summary, the task is to write a program that after reading a positive integer i (from 0 to 1000) will write how many "nice numbers" are in the interval [0..i]. "Nice numbers" are numbers that are divisible by their every digit. For example 612 is a nice number becasuse it is divisible by 6,1 and 2. One the other hand 512 is not a nice number because it is not divisible by 5. And the programmer needs help with it.
  • #1
tawi
33
0
Hello,
My task is to write a program that after reading a positive integer i (from 0 to 1000) will write how many "nice numbers" are in the interval [0..i]. "Nice numbers" are numbers that are divisible by their every digit. For example 612 is a nice number becasuse it is divisible by 6,1 and 2. One the other hand 512 is not a nice number because it is not divisible by 5. And I need a little help with it.

Example of an input:
24

Corresponding output:
14

- in the interval [0,24] we can find these 14 nice numbers:
1 2 3 4 5 6 7 8 9 11 12 15 22 24

Thank you for your help.
 
Physics news on Phys.org
  • #2
I moved your thread to the homework section.
tawi said:
And I need a little help with it.
What do you have so far?
Where did you get stuck?
 
  • #3
Ok, here is what I've got:

program abcd;
var a,b,c,d,x,y,z,w,i: integer;
begin
readln (x);
if (x<10) then
begin
writeln (x);
if (x>10) and (x<100) then
begin
a:=x mod 10;
b:=x div 10;
y=0;
for i=x downto 10 do
begin
if (x mod a = 0) and (x mod b = 0) then
y:=y+1
else
y:=y
end;
writeln (y+9);
if (x>99) and (x<1000) then
...
...
...
end.

The following is pretty much irrelevant. The idea is the same, only the conditions are little different...

I honestly don't know where the problem is. The logic behind that seems fine to me, it compiles fine but it only works for the numbers 0-9. Once we get into longer numbers (with the conditions and cycles) it just wouldn't give me the output. As if it wasn't supposed to write anything.Thans for any help and if there's something unclear, let me know.
 
  • #4
x=10 is not covered.

I would write a function that performs the check, but that's an unrelated point.
Some things look more complicated than necessary.

By the way: you can preserve the indentation by wrapping your code in [code] tags.
Code:
This is a line
     This is an indented line

To see what goes wrong, you can add intermediate outputs in your code (better: use a programming environment where you can follow the program flow).
 
  • #5
I use Borland Pascal but I am just getting to know that enviroment. Haven't gone through functions either so I would prefer some solution without it. What would you simplify?
 
  • #6
For example, where is the point in this?
else
y:=y

if (x<10) then
begin
writeln (x);
Why "begin" and where is the end here? What happens if x is not smaller than 10?
 
  • #7
The first one is unnecessary, I just thought it could be a bit more illustrative with it.

The "end" would be at the very end. But yes, I feel some of the "begin(s)" are the reason behind why it doesn't do what it should.
As to what happens when x is not <10 then there are the other conditions. One for 9<x<100 then for 99<x<1000 and last one for 999<x<10000.. Considering 10000 is the maximum input.
Basicallz what I do here is I first determine how many figures there are in the number (which determines the number of our variables - with two-figure number you have to check if it is dividable by two numbers, three-figure three numbers etc.) and then it goes through the appropriate cycle and in the end should give us how many numbers there are in the certain interval.
To give an example.. Let's say you have the number 14. You know its a two-figure number so you determine how many "nice numbers" are in the interval [10, 14]. You'll get the 2 (11,12) and that is your result for this interval. Considering we want to go down to 0 we just add 9 as all the one-figure numbers are nice numbers.
 
Last edited:
  • #8
tawi said:
Ok, here is what I've got:
Code:
program abcd;
var a,b,c,d,x,y,z,w,i: integer;
begin
readln (x);
   if (x<10) then
   begin
   writeln (x);
          if (x>10) and  (x<100) then
          begin
          a:=x mod 10;
          b:=x div 10;
          y=0;
               for i=x downto 10 do
               begin
               if (x mod a = 0) and (x mod b = 0) then
               y:=y+1
               else
               y:=y
               end;
               writeln (y+9);
                    if (x>99) and (x<1000) then
                    ...
                    ...
                    ...
                    end.
I would start off by assuming that the number can be written with three digits; that is, a number from 1 through 999 inclusive. You can strip off the three digits by doing integer division (using the div operator) with 100 and then 10.

Code:
hundreds := number div 100;
temp := number - hundreds * 100;
tens := temp div 10;
ones := temp mod 10;
After this code executes, hundreds, tens, and ones should be set with the values in those three places. Note that this also works if number has only one or two digits.

One problem with your code is that it skips some numbers such as 10. Another problem is in your logic, due in part to unmatched begin ... end pairs. In your logic above, you're checking to see whether x is less than 10. In the same block, you're checking to see whether x is larger than 10 and smaller than 100. If the number is smaller than 10, it can't possibly be larger than 10.

It's good that you are using indentation to show program structure, but it could use some work.
Instead of this:
Code:
if (x>10) and  (x<100) then
          begin
          a:=x mod 10;
          b:=x div 10;
          y=0;
               for i=x downto 10 do
               begin
do this:
Code:
if (x>10) and  (x<100) then
begin
      a:=x mod 10;
      b:=x div 10;
      y=0;
      for i=x downto 10 do
      begin
         ... body of for loop
      end  { end of for loop}
end { end of if }

It's also a good idea to use variable names that suggest what they're being used for. Instead of a, b, x, and y, names like tens, hundreds, and so on give a better idea to the reader what they're for.
 
  • #9
Mark44 said:
One problem with your code is that it skips some numbers such as 10. Another problem is in your logic, due in part to unmatched begin ... end pairs. In your logic above, you're checking to see whether x is less than 10. In the same block, you're checking to see whether x is larger than 10 and smaller than 100. If the number is smaller than 10, it can't possibly be larger than 10.
.

Ok. I see what you mean but that should be easily fixable by just moving the "end" command behind the appropriate block, right?
Thanks for the other tips, I'll look into it.
 
  • #10
tawi said:
Ok. I see what you mean but that should be easily fixable by just moving the "end" command behind the appropriate block, right?
I think you're better off starting from scratch, rather than trying to patch what you have.
 
  • #11
The idea with writing any number by using three digits occurred to me as well but I didn't see any way how to work with it further. At some point there's going to have to be a condition that determines whether the number is "nice" or not. And you are going to have to check if the x mod (hundreds), x mod (tens) and x mod (ones) are all 0 at the same time. But if, for example, your hundreds are 0 then it will not be true because division by 0 is undefined.
 
  • #12
tawi said:
The idea with writing any number by using three digits occurred to me as well but I didn't see any way how to work with it further. At some point there's going to have to be a condition that determines whether the number is "nice" or not. And you are going to have to check if the x mod (hundreds), x mod (tens) and x mod (ones) are all 0 at the same time. But if, for example, your hundreds are 0 then it will not be true because division by 0 is undefined.
After you strip off the digits, you can have logic to see how big the number is. If the hundreds digit is 0, then you know that the number is in the interval [1..99]. If the tens digit is 0, then you know that the number is in the interval [1..9].

I'm assuming here that the number is positive, so my intervals don't include 0.
 
  • #13
Of course but that will lead me to pretty much the same conditions I have above, right? Just a bit simplified.. As you are saying I can set a condition whre if hundreds and tens are zero we are dealing with number 0-9, if hundreds are 0 and tens aren't we are in 0-99 and then, for the individual intervals I will need the for cycles to check whether the numbers [0,x] are divisible by its figures. Or am I wrong?
 
  • #14
tawi said:
Of course but that will lead me to pretty much the same conditions I have above, right? Just a bit simplified.. As you are saying I can set a condition whre if hundreds and tens are zero we are dealing with number 0-9, if hundreds are 0 and tens aren't we are in 0-99 and then, for the individual intervals I will need the for cycles to check whether the numbers [0,x] are divisible by its figures. Or am I wrong?
That's roughly the idea, but what I'm suggesting is more organized.
Strip off the digits, using the idea in the code sample I gave.
After that, work your way down, one digit at a time, from the hundreds down to the ones digit.
If the hundreds digit is zero, you have a number in the interval [1 ... 999] and you can check to see if the 3-digit number is "nice".
Otherwise, if the tens digit is not zero, you have a number in the interval [1 ... 99], and you can check to see if the 2-digit number is "nice".
Otherwise, if the ones digit is not zero, you have a number in the interval [1 ... 9], and you can check to see if the 1-digit number is "nice".

The algorithm I've laid out presumes that the number is larger than 0 and smaller than 1000.
 
  • #15
I understand, seems fine. Only the part with the cycle seems to be not working for me. Not sure what I am not doing right. In the example above, can you see any problems with how the for cycle is written? if we say some variable "result" is 0 at the beginning and with every "nice number" going down from x to 0 increases by one, then we should get the correct result at the end, shouldn't we? It gives me outputs that aren't correct and I am wondering if the way the cycle is written is flawed.
 
  • #16
tawi said:
can you see any problems with how the for cycle is written?
Take x=14 as example input and follow the code flow line by line that gets executed. Hint: it is very short, and it is related to the begin and end I highlighted.
 
  • #17
Mark44 said:
That's roughly the idea, but what I'm suggesting is more organized.
Strip off the digits, using the idea in the code sample I gave.
After that, work your way down, one digit at a time, from the hundreds down to the ones digit.
If the hundreds digit is zero, you have a number in the interval [1 ... 999] and you can check to see if the 3-digit number is "nice".
Otherwise, if the tens digit is not zero, you have a number in the interval [1 ... 99], and you can check to see if the 2-digit number is "nice".
Otherwise, if the ones digit is not zero, you have a number in the interval [1 ... 9], and you can check to see if the 1-digit number is "nice".

The algorithm I've laid out presumes that the number is larger than 0 and smaller than 1000.

The problem is that if the number has 3 digits and I start checking if that number is "nice" I also need to check how many nice numbers there are in between our x and 0.
And the problem appears when the 3-digit numbers turn to 2-digit numbers and when those turn into 1-digit numbers.. The algorithms or the conditions are different and I don't know how to connect them. The only thing that comes to mind is letting the program determine how many nice numbers there are in all 2-digit numbers and 1-digit numbers and then add those numbers to your result for 3-digit numbers...

I fell like I know exactly what I need to do but I do not know how to put that in the code so it will actually work. For example the begins and ends. I've tried to put them in places where I think they make sense but the outputs were wrong...
For example the code that should tell you how many nice numbers there are in only the 3-digit number interval [100..x]

Using the code sample from above I could write something like this:
Code:
if hundreds <> 0 then
result1:=0;
for i:=x downto 100 do
if (i mod hundreds = 0) and (i mod tens = 0) and (i mod ones = 0) then
result1:=result1 + 1;
writeln (reslut1);

Now I have left all the "begins" and "ends" out.. Where will they go considering there will be other blocks behind this determining the same thing for numbers from different intervals? Whatever I tried the for cycle just wouldn't work. The output would be just wrong.
I tried writing a simple program that would determine whether just the input is a nice number, that is without problem using the same method, just no cycle, which leads me to the conclusion the mistake is somewhere there. Only one more thing I noticed. Everytime the input is a number ending with a 0 the program gives and dividing by 0 error.. How to work around that in this case?
I really want to understand this so all the help is appreciated:)
 
Last edited:
  • #18
You are looking at the wrong place. Did you follow my suggestion? What was the result?
 
  • #19
Yes, the end was missing before the second if. Tried to fix it that way but the results would be bad whatever I did.
I ended up defining a function that pretty much does the same thing I did in all those intervals and then I send it through one for cycle at the end. Works perfectly.
 
  • #20
I missed the part in your first post that you have to check all of the numbers from the input number on down. Here's how I would do this problem:

Prompt user to enter an integer in the range 1 through 999, inclusive.
Determine the digits of the input number, as already discussed.
Use a for loop to iterate from 1 through number, checking each
tawi said:
Yes, the end was missing before the second if. Tried to fix it that way but the results would be bad whatever I did.
I ended up defining a function that pretty much does the same thing I did in all those intervals and then I send it through one for cycle at the end. Works perfectly.
Good. Yes, writing a function to do the check makes sense.

In my earlier posts I misunderstood the requirements of the problem, thinking that you only had to check one input number to see if it was "nice."

Does your code correctly handle numbers such as 403 and 510? Your code should have logic in it to eliminate numbers such as these from consideration.
 
  • #21
Yes, I actually extended all the conditions and made sure it handles every number correctly. I am not quite sure what you mean by eliminating them. I just made another condition that checks if any of the digits is 0 and if it is, it automatically considers the number not "nice".
Here's my version, I am sure lots of it can be simplified but it still seems pretty straightforward and clear. And most importantnyl, it works..

Code:
function nNumb (x: integer): integer;

begin

{here I define my variables for individual digits such as:}

thousands := x div 1000;
hundreds := ...
...
ones:= ...  if (x > 0) and (x < 10) then
  result:=1;
 
  if (x > 9) and (x < 100) then
  if (ones <> 0) then
  if (x mod ones = 0) and (x mod tens = 0) then
  result:=1;
 
  if (x > 99) and (x < 1000) then
  if (ones <> 0) and (tens<> 0) then
  if (x mod ones= 0) and (x mod tens= 0) and (x mod hundreds= 0) then
  result:=1;

  nNumb:=result;

  begin

  readln (input);
 
  for i:=input downto 0 do
  begin
  y:=y+nNumb(i);
  end;
 
  writeln (y);
  end.
Sorry for the indentation, it pasted strangely.. This is just a shorter version (I actually made it for all integers up to 32767) but you get the idea.
 
Last edited:
  • #22
Here's some Python code I wrote for your original problem.
Python:
# nice.py - from input value N, of at most three digits, determine all "nice" numbers in the interval 1..N
# A "nice" number is one for which all of its digits divide the number

import string

# Determine whether number is "nice"
def checkNice(number):
     global count

     # All numbers in interval [1 .. 9] are nice
     if number >= 1 and number < 10:
        outstr = '{0:d} is nice'.format(number)
        print(outstr)
        count += 1

     # number has two digits  
     elif number < 100:
        ones = number % 10
        tens = number // 10
        # Skip over numbers whose ones' digit is 0,
        #  and check that each digit divides number
        if ones is not 0 and number % ones == 0 and number % tens == 0:
        outstr = '{0:d} is nice'.format(int(number))
        print(outstr)
        count += 1
  
     # number has three digits  
     else:
        ones = number % 10
        tens = (number // 10) % 10
        hundreds = number // 100
 
        # Skip over numbers whose tens' digit is 0, or whose ones' digit is 0,
        #  then check that all three digits divide number
        if ones is not 0 and tens is not 0:
           if number % ones == 0 and number % tens == 0 and number % hundreds == 0:
              outstr = '{0:d} is nice'.format(int(number))
              print(outstr)
              count += 1# Prompt for an input value
N = int(input('Enter a positive integer N of at most 3 digits: '))

# Global variable for keeping track of how many nice numbers were found
count = 0 
# Exit early if input value is nonpositive or larger than 999
if N <= 0 or N > 999:
  print('Input value out of range')
  exit

else:
  for i in range(N + 1):
  checkNice(i)

outstr = 'Found {0:d} nice numbers'.format(count)
print(outstr)
 

Related to Find Nice Numbers: A Program to Count Divisible Digits in Range [0,1000]

What is the purpose of the "Find Nice Numbers" program?

The purpose of the "Find Nice Numbers" program is to count the number of digits in the range of 0 to 1000 that are divisible by a given number.

What types of numbers can be counted using this program?

This program can count any whole numbers (integers) in the range of 0 to 1000.

How is the program able to determine if a number is divisible by a given number?

The program uses the modulo operator (%) to determine if a number is divisible by another number. If the result of the modulo operation is 0, then the number is divisible by the given number.

Can this program count the number of digits in a larger range?

Yes, the program can be easily modified to count the number of digits in a larger range by changing the upper limit of the range. However, for extremely large ranges, the program may take longer to run.

Is this program accurate for all numbers and ranges?

Yes, the program is accurate for all numbers and ranges as long as the input is within the specified range (0 to 1000). If the input is outside of this range, the program may not give accurate results.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
4
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
6
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Programming and Computer Science
Replies
4
Views
2K
Replies
19
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
5K
  • General Discussion
Replies
8
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
7K
Back
Top