Transcript PPT
Additional Problems
Smallest Divisor of an integer
Problem: Given an integer m, write a program that will
find its smallest exact divisor other than 1.
• Is the problem clear and well-defined?
• what is a divisor?
–
–
–
–
–
–
For any number m, there are divisors
There are at least two divisors
All divisors of m can be totally ordered
Can m be 0?
Can it be negative?
What if m is prime?
• Assume: m > 0
• Assert: if m is prime, return 1 else the smallest divisor
other than 1
Towards a strategy
• All divisors of m are between 1 and m
• Strategy 1:
– Enumerate all divisors of m
– choose the smallest one
• Better Strategy:
– Starting from 2, check one by one whether it is
a divisor of m
– If one is found before m is reached then return.
– Otherwise, return 1.
• How to check a divisor?
• Can we do better?
Towards a Better Strategy
• The above inspects (m-1) numbers, in the
worst case
– for even numbers, the answer is 2
– for odd numbers, no need to check an even
number
• How to check whether a number is even or
not?
• Do we have go up to m?
The Algorithm
Algorithm st_divisor
Input m
Assume: m > 0
Output d
Assert: if m is prime, d is 1; otherwise,
d is the smallest divisor other than 1
1. if ( even(m)) then d = 2
else
1.1 d = 3
1.2 do while ((m mod d /= 0 ) and (d < sqrt(m)))
1.2.1 d = d + 2
2. if (m mod d /= 0) then d = 1
end algorithm
Observation
• How to compute Square roots?
• Better to remove the square root computation
before the loop
– Look for removing computations inside loops
• Note m mod d can not be removed
• Is the algorithm correct?
• Does it terminate?
Loop invariant
• The invariant condition is:
m is odd, d is odd, 1 < d <= sqroot(m) + 1
for no x: 1 < x < d: x is a divisor of m
• Bound Function:
(m – d)
Improvements
• How many iterations?
– In the worst case, the largest integer less than
or equal to sqroot(m)/2
– 0, if m is even
• Is there a better algorithm?
– A lot of redundant checks are still made
– Look for prime divisors
The square root problem
• Problem: Write a program that computes the
square root of a given number.
• Is the problem definition clear?
– If 25 is the input, then 5 is the output
– If 81 is the input, then 9 is the output
– If 42 is the input, then ?
• For non perfect squares, the square root is a real
number
• So the output should be close to the real square
root
• How close? to a given accuracy
A more precise specification
• Problem: Write a program that given a
number m outputs a real value r s.t. r*r differs
from m by a given accuracy value e
• More precisely, the program outputs r s.t.
|r*r - m| < e
Solution Strategy
Guess and Correct Strategy:
1. Choose an initial guess r less than m
2. If r*r > m then keep decreasing r by 1 until r*r
is less than or equal to m.
3. If r*r < m then keep increasing r by 0.1, …
until r*r exceeds or equals m
4. If r*r > m then decrease r by 0.01 until r*r
exceeds or equals m.
...
• Terminate the computation when r*r equals
m or differs from m by a given small number.
Idea
• Number of iteration depends upon the initial guess
• If m is 10,00,000 and the initial guess is 300 then
over 700 steps are needed
• Can we have a better strategy?
Towards a better strategy
• The basic idea of the strategy is to obtain a
series of guesses that
– falls on either side of the actual value
– narrows down closer and closer
• To make the guess fall on either side
– increase/decrease the guess systematically
• To narrow the guess
– the amount of increase/decrease is reduced
• Improving the strategy
– faster ways of obtaining new guess from the old
one
One Strategy
• Given a guess a for square root of m
– m/a falls on the opposite side
– (a + m/a)/2, can be the next guess
• This gives rise to the following solution
– start with an arbitrary guess, r_0
– generate new guesses r_1, r_2, etc by using
the averaging formula.
• When to terminate?
– when the successive guesses differ by a given
small number
The algorithm
Algorithm Sq_root
Input m, e: real
assume: m>0, 1 > e > 0
Output r1, r2: real
assert:: |(r2 * r2 - m) | <= |(r1 * r1 - m)|, |r1 - r2| < e
1. r1 = m/2
2. r2 = r1
3. Do while (|r1 - r2| > e) steps 3.1 and 3.2
3.1 r1 = r2
3.2 r2 = (r1+m/r1)/2
end Algorithm
Analysis of the algorithm
• Is it correct? Find the loop invariant and
bound function
• Can the algorithm be improved?
• More general techniques available
– Numerical analysis