Egyptian division

From Rosetta Code
Revision as of 20:26, 7 August 2017 by rosettacode>Paddy3118 (New task and Python example.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Egyptian division is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Egyptian division is a method of dividing integers using addition and doubling that is similar to the algorithm of Ethiopian multiplication

Algorithm:

Given two numbers where the dividend is to be divided by the divisor:

  1. Start the construction of a table of two columns: powers_of_2, and doublings;

by a first row of a 1 (i.e. 2^0) in the first column and 1 times the divisor
in the first row second column.

  1. Create the second row with columns of 2 (i.e 2^1), and 2 * divisor in order.
  2. Continue with successive i’th rows of 2^i and 2^i * divisor.
  3. Stop adding rows, and keep only those rows, where 2^i * divisor is less than or

equal to the dividend.

  1. We now assemble two separate sums that both start as zero, called here

answer and accumulator

  1. Consider each row of the table, in the reverse order of its construction.
  2. If the current value of the accumulator added to the doublings cell would be

less than or equal to the dividend then add it to the accumulator, as well as
adding the powers_of_2 cell value to the answer.

  1. When the first row has been considered as above, then the integer division of

dividend by divisor is given by answer.

(And the remainder is given by the absolute value of accumulator - dividend).

Example: 580 / 34

Table creation:

powers_of_2 doublings
1 34
2 68
4 136
8 272
16 544

Initialization of sums:

powers_of_2 doublings answer accumulator
1 34
2 68
4 136
8 272
16 544
0 0

Considering table rows, bottom-up:

When a row is considered it is shown crossed out if it is not accumulated, or bold if the row causes summations.

powers_of_2 doublings answer accumulator
1 34
2 68
4 136
8 272
16 544 16 544
powers_of_2 doublings answer accumulator
1 34
2 68
4 136
8 272 16 544
16 544
powers_of_2 doublings answer accumulator
1 34
2 68
4 136 16 544
8 272
16 544
powers_of_2 doublings answer accumulator
1 34
2 68 16 544
4 136
8 272
16 544
powers_of_2 doublings answer accumulator
1 34 17 578
2 68
4 136
8 272
16 544

Answer

So 580 divided by 34 using the Egyptian method is 17 remainder (578 - 580) or 2.

Task

The task is to create a function that does Egyptian division. The function should
closely follow the description above in using a list/array of powers of two, and
another of doublings.

  • Functions should be clear interpretations of the algorithm.
  • Use the function to divide 580 by 34 and show the answer here, on this page.

Python

<lang python>def egyptian_divmod(dividend, divisor):

   assert divisor != 0
   pwrs, dbls = [1], [divisor]
   while dbls[-1] <= dividend:
       pwrs.append(pwrs[-1] * 2)
       dbls.append(pwrs[-1] * divisor)
   ans, accum = 0, 0
   for pwr, dbl in zip(pwrs[-2::-1], dbls[-2::-1]):
       if accum + dbl <= dividend:
           accum += dbl
           ans += pwr
   return ans, abs(accum - dividend)
  1. Test it gives the same results as the divmod built-in

from itertools import product for i, j in product(range(13), range(1, 13)):

       assert egyptian_divmod(i, j) == divmod(i, j)
  1. Mandated result

i, j = 580, 34 print(f'{i} divided by {j} using the Egyption method is %i remainder %i'

     % egyptian_divmod(i, j))</lang>

Sample output

580 divided by 34 using the Egyption method is 17 remainder 2