I'm supposed to code a procedure that finds all integers that evenly divide a number, and I've come up with a solution that works; unfortunately with my non-existent coding knowledge, I don't know why it works.
Here's the basic code:
Get(Number)
A:=1
for X in 1..Number-1 loop
A:=A+1;
C:=Number/A;
if C*A = Number then
Put(A)
end if;
end loop;
I've edited out some pure puts for readability, I understand that A
increases with 1 each step of the loop, but I don't quite understand what number C
retains each loop. I've tried backtracking by printing it, and it goes between the values 2 and 1 for a value of 10 on the "number". Instead of being 1 or 2, I'd see it as being 10/1, 10/2, 10/3, 10/4, 10/5, 10/6 etc, meaning once we reach the if statement we'll just have, lets say, 10/4*A where A is 4 and viola we get 10 even though 10 isn't divisible by 4.
How is C updated, can anyone explain in simple terms?
I assume that the integers to find must be positive. In that case, the type of Number
, A
, C
and X
could instead be Positive
. If the input is not a positive number, then a CONSTRAINT_ERROR
exception will be raised. This is safer: an exception clearly indicates that something went wrong, and it is better than returning an incorrect result.
Note that the program never tests whether 1
is a valid divisor, even though it is. This is because A
is incremented at the beginning of the loop; since its starting value is 1
, the first checked value is 2
. In any case, it is better to use X
, the loop's variable. On your program, it will take values ranging from 1
until Number - 1
, both ends included. In addition, X
will behave like a constant inside the loop body, which eliminates the risk of accidentally overwriting its value.
The value assigned to C
is the result of dividing Number
over A
. Given that these variables are integers, the division result will be truncated. For positive numbers, this is equivalent to "rounding down" the result. If Number
is evenly divided by A
, then the remainder will be zero, so the multiplication will result in the original value. Otherwise, the remainder will be lost, so the value of C * A
will be less than the value of A
.
A simpler approach is to directly calculate the remainder of both numbers, and then check whether it is zero. This is the resulting code:
procedure Main is
Number : Positive;
begin
Get (Number);
for A in 1 .. Number loop
if Number rem A = 0 then
Put (A);
end if;
end loop;
end Main;