Programming Problems for CS Students
Programming Problems for CS Students
Reg Dodds
Department of Computer Science
University of Stellenbosch
rdodds@[Link]
The problems in this chapter are based mainly on the properties of numbers.
We consider the digits of a number, the factors of a number, be they prime
or not, the primacy of a number, and other related problems.
Problem 1.1 Count the number of digits in integer n
Calculate the number of decimal digits of the integer n.
1
these iterations as follows. We initialize the number of digits m to zero and
at each step replace n by its value with its last digit removed.
1 m = 0
2 while n > 0:
3 n = n // 10
4 m = m + 1
However, this will usually be programmed by using the ‘operate-and-becomes’
notation and embedding the code in a function.
1 def noDigits(n):
2 m = 0
3 while n > 0:
4 n //= 10
5 m += 1
6 return m
7
8 m = noDigits(n)
The variable n is unaffected by the invocation m = noDigits(n). This is not
the last word. Python has some useful built-in operators that should be
used when programming this problem. The str() function can be used to
turn the integer into a string, and the len() function counts the number of
characters in the string. The call below gives the same result.
1 m = len(str(n))
———
nm = n × n × n × . . . m times.
2
1 product = 1
2 for count in range(m):
3 product = product * n
This seems to be the last word, but it is rather inefficient. We will dis-
cuss more efficient ways of doing later in Problem 4.9. In the mean time
we will use the function below to do integer exponentiation. It takes m
multiplications.
1 def power(n, m):
2 product = 1
3 for count in range(m):
4 product = product * n
5 return product
When the power is negative we proceed in the same way for |m| multiplica-
tions but invert the product. We use a boolean variable called negativePower
that becomes True when the power is negative to keep track of what action
to take.
1 def power(n, m):
2 product = 1
3 negativePower = False
4 if m < 0:
5 negativePower = True
6 m = -m
7 for count in range(m):
8 product = product * n
9 if negativePower:
10 product = 1/product
11 return product
———
n = dm−1
1 10m−1 + dm−2
2 10m−2 + . . . + d2m−2 102 + dm−1 10 + dm
3
number, then that number is said to be an Armstrong number, that is, n is
an Armstrong number if the following equality holds
n = dm m m m m
1 + d2 + . . . + dm−2 + dm−1 + dm
4
1 n = int(input("Enter an integer: "))
2 m = 0
3 copyOfn = n
4 while n > 0:
5 ndiv10 = n // 10
6 m += 1
7 digit = n - ndiv10 * 10
8 n = ndiv10
9 n = copyOfn
10 # followed by Armstrong code
Expanding this gives
1 n = int(input("Enter an integer: "))
2 m = 0
3 copyOfn = n
4 while n > 0:
5 ndiv10 = n // 10
6 m += 1
7 digit = n - ndiv10 * 10
8 n = ndiv10
9 print (m)
10 n = copyOfn
11 # Determine if n is an Armstrong number
12 armstrong = 0
13 while n > 0:
14 ndiv10 = n // 10
15 digit = n - ndiv10 * 10
16 armstrong += digit ** m
17 n = ndiv10
18 n = copyOfn
19 if n == armstrong:
20 print("%d is an Armstrong number\n" % n)
———
5
3 m = 0
4 copyOfn = n
5 while n > 0:
6 ndiv10 = n // 10
7 digits[m] = n - ndiv10 * 10
8 n = ndiv10
9 m += 1
10 n = copyOfn
11 # Determine if n is an Armstrong number
12 armstrong = 0
13 for i in range(m):
14 armstrong += digits[i] ** m
15 if n == armstrong:
16 print("%d is an Armstrong number\n" % n)
———
1 # James untouched
2 digits : array[1..100] of number
3
4 get num from user
5 set cnt = 0
6 while num <> 0 do
7 begin block
8 set cnt = cnt + 1
9 set digits[cnt] = remainder of num/10
10 set num = integer part of num/10
11 end block
12 set total = 0
13 for i ranges from 1 to cnt do
14 set total = total + digits[i]\^cnt
15 if num = total then display num is an Armstrong number
1 set number = 0
2 set num = 1
3 repeat
4 set count = 0
5 while num <> 0 do
6 begin block
7 set count = count + 1
8 set digits[count] = remainder of num/10
6
9 set num = integer part of num/10
10 end block
11 set total = 0
12 for i ranges from 1 to count do
13 set total = total + digits[i]^count
14 if num = total then
15 begin block
16 display num
17 set number = number + 1
18 end block
19 set num = num + 1
20 until number = 15
Problem 1.6 Find all the n < 10000 with nondecreasing digits
Examples of such numbers are 11, 12, . . . , 19, 22, 23, . . . , 29, 33, 34, . . . , 39.
Problem 1.7 Find all the n < 1000 with nondecreasing digits that
also have squares with nondecreasing digits
Examples of such numbers are 122 = 144i, 132 = 169, 152 = 225, 162 = 256,
372 = 1369.
7
16 end block
17
18
19 where Base^n is Base to the power of n
———
Solution— 2
This can easily be rewritten as
1 get Num from user
2 get Base from user
3
4
5 for n ranges from x to 0 do
6 begin block
7 if Num > Base^n then
8 begin block
9 display integer part of Num/(Base^n)
10 set Num = remainder of Num/(Base^n)
11 end block
12 end block
———
However, we are still restricted by the size of x and 210 = 1024 is much
smaller than 910 = 3486784401
Solution— 3
We know that we can convert a number from base ten to any base by re-
peatedly dividing by the base. So we have
1 get Num from user
2 get Base from user
3
4 repeat
5 display remainder Num/Base
6 set Num = integer part of Num/Base
7 until Num = 0
———
Solution— 4
As a while loop
8
1 get Num from user
2 get Base from user
3
4 while (Num <> 0) do
5 begin block
6 display remainder Num/Base
7 set Num = integer part of Num/Base
8 end block
9 Implement a binary search algorithm that displays
10 the index of the desired value and the number of
11 lookups [Link] a bubble sort [Link] a program that allows the user
12 to play blackjack against the computer.
———
When a cash purchase is made, the cashier normally has to give the
customer change. The customer does not want a bulky wallet, so it is up
to the cashier to give the customer the smallest number of notes and coins.
Write an algorithm to assist the cashier in determining which notes and
coins to give the customer.
Answer
What do we need? The total of the purchase made. The amount ten-
dered.
What do we know? The following notes and coins are available to us:
R200, R100, R50, R20, R10, R5, R2, R1, 50c, 20c, 10c, 5c, 2c, 1c
What do we want to do? We want to minimize the number of coins
and notes used, so we want to always use the biggest (in value) notes and
coins possible. So we start with the biggest denomination and work our way
down, each time calculating how many of that denomination to return.
Solution— 1
9
7 display R200 x integer part of Change/R200
8 set Change = remainder of Change/R200
9 end block
10 if Change >= R100 then
11 begin block
12 display R100 x integer part of Change/R100
13 set Change = remainder of Change/R100
14 end block
15 if Change >= R50 then
16 begin block
17 display R50 x integer part of Change/R50
18 set Change = remainder of Change/R50
19 end block
20 if Change >= R20 then
21 begin block
22 display R20 x integer part of Change/R20
23 set Change = remainder of Change/R20
24 end block
25 if Change >= R10 then
26 begin block
27 display R10 x integer part of Change/R10
28 set Change = remainder of Change/R10
29 end block
30 if Change >= R5 then
31 begin block
32 display R5 x integer part of Change/R5
33 set Change = remainder of Change/R5
34 end block
35 if Change >= R2 then
36 begin block
37 display R2 x integer part of Change/R2
38 set Change = remainder of Change/R2
39 end block
40 if Change >= R1 then
41 begin block
42 display R1 x integer part of Change/R1
43 set Change = remainder of Change/R1
44 end block
45 if Change >= 50c then
46 begin block
47 display 50c x integer part of Change/50c
48 set Change = remainder of Change/50c
49 end block
50 if Change >= 20c then
51 begin block
10
52 display 20c x integer part of Change/20c
53 set Change = remainder of Change/20c
54 end block
55 if Change >= 10c then
56 begin block
57 display 10c x integer part of Change/10c
58 set Change = remainder of Change/10c
59 end block
60 if Change >= 5c then
61 begin block
62 display 5c x integer part of Change/5c
63 set Change = remainder of Change/5c
64 end block
65 if Change >= 2c then
66 begin block
67 display 2c x integer part of Change/2c
68 set Change = remainder of Change/2c
69 end block
70 if Change >= 1c then
71 begin block
72 display 1c x integer part of Change/1c
73 set Change = remainder of Change/1c
74 end block
———
Solution— 2
The algorithm above solves the problem, but is not very elegant. It
would be nice if we could find a way of using a loop rather than writing so
many if statements. We notice that the pattern 5xx, 2xx, 1xx is repeated.
In fact, if we had a R500 note, we would have had the same pattern 5xx,
2xx, 1xx repeated 5 times, decreasing by a factor 10 every time. So we will
use this to to implement a more elegant solution. In order to make it easier
for reader to follow, it will be assumed that all amounts are in cents instead
of Rands and cents. (Converting all amounts to cents can easily be achieved
multiplying by 100.)
1 get purchase Total from user
2 get Amount tendered from user
3 set Change = Amount - Total
4
11
8
9 repeat
10 if (Change >= One) and (One < 50000) then
11 begin block
12 if One >= 500 then
13 display R(One/100) x integer part of Change/One
14 else display (One)c x integer part of Change/One
15 set Change = remainder of Change/One
16 set One = One/10
17 end block
18 if (Change >= Two) then
19 begin block
20 if Two >= 200 then
21 display R(Two/100) x integer part of Change/Two
22 else display (Two)c x integer part of Change/Two
23 set Change = remainder of Change/Two
24 set Two = Two/10
25 end block
26 if (Change >= Three) then
27 begin block
28 if Three >= 100 then
29 display R(Three/100) x integer part of Change/Three
30 else display (Three)c x integer part of Change/Three
31 set Change = remainder of Change/Three
32 set Three = Three/10
33 end block
34 until Change = 0
———
Solution— 3
12
13 if One >= 500 then
14 display R(One/100) x integer part of Change/One
15 else display (One)c x integer part of Change/One
16 set Change = remainder of Change/One
17 set One = One/10
18 end block
19 if (Change >= Two) then
20 begin block
21 if Two >= 200 then
22 display R(Two/100) x integer part of Change/Two
23 else display (Two)c x integer part of Change/Two
24 set Change = remainder of Change/Two
25 set Two = Two/10
26 end block
27 if (Change >= Three) then
28 begin block
29 if Three >= 100 then
30 display R(Three/100) x integer part of Change/Three
31 else display (Three)c x integer part of Change/Three
32 set Change = remainder of Change/Three
33 set Three = Three/10
34 end block
35 end block
———
Solution— 4
13
7
8 while (Change <> 0) do
9 begin block
10 if (Change >= Denomination) then
11 begin block
12 if Denomination >= 100 then
13 display R(Denomination/100) x integer part of Change/Denomination
14 else display (Denomination)c x integer part of Change/Denomination
15 set Change = remainder of Change/Denomination
16 end block
17 if Cnt is divisible by 3 then set Denomination = 2*Denomination/5
18 else set Denomination = Denomination/2
19 set Cnt = Cnt + 1
20 end block
———
Solution— 5
We can also use our knowledge of arrays to solve the problem. We use
a two dimensional array to store the number of each denomination needed.
First we initialize the array with the denominations and we zero the number
for each.
Money is an array[1..2][1..14] of numbers.
1 get purchase Total from user
2 get Amount tendered from user
3 set Change = Amount - Total
4
5 set Denomination = 20000
6
7 for Index ranges from 1 to 14 do
8 begin block
9 set Money[1][Index] = Denomination
10 set Money[2][Index] = 0
11 if Index is divisible by 3 then
12 set Denomination = 2*Denomination/5
13 else set Denomination = Denomination/2
14 end
15
16 set Cnt = 1
17
18 while (Change <> 0) do
19 begin block
20 if Change >= Money[1][Cnt] then
14
21 begin block
22 set Money[2][Cnt] = integer part of Change/Money[1][Cnt]
23 set Change = remainder of Change/Money[1][Cnt]
24 end block
25 set Cnt = Cnt + 1
26 end block
27
28 set Cnt = 1
29
30 while (Money[1][Cnt] >= 100) do
31 begin block
32 if Money[2][Cnt] > 0 then
33 display R(Money[1][Cnt]/100) x Money[2][Cnt]
34 set Cnt = Cnt + 1
35 end block
36
37 repeat
38 if Money[2][Cnt] > 0 then
39 display (Money[1][Cnt])c x Money[2][Cnt]
40 set Cnt = Cnt + 1
41 until Cnt > 14
———
In plain English
1. Get the number to check.
15
4. If the number is divisible by any of these numbers, then it is not prime,
otherwise it is prime.
In pseudocode
1 get Num from user
2 get IsPrime = True
3 for PFactor ranges from 2 to Num-1 do
4 begin block
5 if Num divisible by PFactor then set IsPrime = False
6 end block
7 if IsPrime = True then display Num is prime
8 else display Num is not prime
———
2. Check all potential factors until the factor is greater than the square
root of the number or we find a factor that divides into the number
without a remainder.
In pseudocode
1 repeat loop
2
3 get Num from user
4 set PFactor = 1
5 repeat
6 set PFactor = PFactor + 1
7 until (PFactor > square root of (Num)) or (Num divisible by PFactor)
8 if PFactor <= square root of (Num) then display Num is not prime
9 else display Num is prime
10
11 while loop begin block
12 get Num from user
16
13 set PFactor = 2
14 while (PFactor <= square root of (Num)) and (Num not divisible by PFactor)
15 begin block
16 set PFactor = PFactor + 1
17 end block
18 if PFactor <= square root of (Num) then display Num is not prime
19 else display Num is prime
———
Problem 1.11 Write a program that will convert and angle from
decimals to degrees minutes and seconds.
Solution— 1
17
Solution— GCD version 2
We can reduce the execution time of the algorithm by first checking if the
smaller number is the GCD and then checking all numbers less then it and
stopping as soon as we find a factor.
1 get x from user
2 get y from user
3
4 if x > y then set Smaller = y
5 else Smaller = x
6
Solution— 3
Two millennia and three centuries ago Euclid presented us with an even
more elegant solution. He showed that
1 GCD(x, y) = GCD(y, remainder of x/y) if y > 0
2 GCD(x, y) = x if y = 0
3
4 In pseudocode this is:
5
18
Solution— GCD of a list numbers
The GCD of three or more numbers can be found by finding the GCD of
pairs of numbers. That is:
1 GCD (x, y, z) = GCD (x, GCD (y, z)) or GCD (x, y, z) = GCD ( GCD (x, y), z)
———
12 While not((x divisible by GCD) and (y divisible by GCD) and (z divisible by GCD)) do
13 set GCD = GCD - 1
14 display GCD
———
19
What is the LCM?
It is the smallest number that is divisible by both x and y. That is, into
which both x and y will divide without leaving a remainder.
What do we know about the LCM?
The LCM must be greater than or equal to the larger of x and y. The
LCM must be less than or equal to the product of the x and y.
Solution— LCM 1
7
8 for PLCM ranges from (x*y) to Greater do
9 if (PLCM is divisible by x) and (PLCM is divisible by y) then set LCM = PLCM
10 display LCM
———
Solution— 2
Solution 1 will always check all numbers between the larger (of x and y) and
the product (of x and y). We can also rewrite the algorithm in such a way
that it will only check numbers up to and including the LCM and then stop.
1 get x from user
2 get y from user
3
4 if x > y then set Greater = x
5 else set Greater = y
6
20
has no definite value until the condition for the if statement is satisfied.
———
Solution— LCM 3
We know that if one number is divisible by another number, then the first
number must be a multiple of the second number. That is, 100 is divisible
by 10. 100 is a multiple of 10. 10 x 10 = 100. Only multiples of 10 will
be divisible by 10 (10, 20, 30, ...). We therefore do not even need to check
numbers between 10 and 20, or 20 and 30, etc. Solution 2 can therefore be
improved as follows:
1 get x from user
2 get y from user
3
4 if x > y then set Greater = x
5 else set Greater = y
6
7 set PLCM = Greater
8 set LCM = 1
9
10 repeat
11 if (PLCM is divisible by x) and (PLCM is divisible by y) then set LCM = PLCM
12 set PLCM = PLCM + Greater
13 until (LCM is divisible by x) and (LCM is divisible by y)
14 display LCM
———
Solution— LCM 4
21
Note: We are checking the loop termination condition before changing
PLCM, so we do not need to make a copy of it. When the loop terminates,
PLCM will be the LCM. Also, the not can be moved into the bracket,
changing the condition from not((PLCM is divisible by x) and (PLCM is
divisible by y)) to (PLCM is not divisible by x) or (PLCM is not divisible
by y) ———
22
21 end block
22 set cnt3 = cnt3 + 1
23 end block
24 if cnt1 > n then
25 begin block
26 for i ranges from 0 to m-cnt2 do
27 set arrthree[cnt3+i] = arrtwo[cnt2+i]
28 end block
29 else
30 begin block
31 for i ranges from 0 to n-cnt1 do
32 set arrthree[cnt3+i] = arrone[cnt1+i]
33 end block
34 end block
———
23
3 Start with 2
4 Repeat
5 Assume the number is prime
6 Test divisibility of the number by all possible numbers
7 between 1 and the number itself
8 If the number is divisible by one of these numbers, then
9 it is not prime,
10 Otherwise
11 it is prime,
12 count it
13 Until we have found N primes
In slightly more exact pseudocode
1 repeat loop
2
3 get N from user
4 set Count = 0
5 set Num = 2
6 repeat
7 set PFactor = 1
8 repeat
9 set PFactor = PFactor + 1
10 until (PFactor > square root of (Num)) or (Num divisible by PFactor)
11 if (PFactor <= square root of (Num)) then display Num is not prime
12 else
13 begin block
14 display Num is prime
15 set Count = Count + 1
16 end block
17 until Count = N
Another more refined version
1 while loop
2
3 get N from user
4 set Count = 0
5 set Num = 2
6 while Count < N do begin block
7 set PFactor = 2
8 while (PFactor < square root of (Num)) and
9 (Num not divisible by PFactor) do
10 set PFactor = PFactor + 1
11
12 if (PFactor <= square root of (Num)) then
13 display Num is not prime
24
14 else begin block
15 display Num is prime
16 set Count = Count + 1 end block end block
———
Find the approximate area under the curve by calculating and summing the
areas of each rectangle of width xi − xi+1 and height f (xi ).
Solution— Integration
We slice the area under the graph into n rectangles and calculate the area of
each rectangle. Summing the areas of each rectangle will yield an approxi-
mation for the total area under the graph.
If we substitute a value for x into the equation, we get the corresponding y
value. This y = f (xi ) value represents the height of the rectangle. Using xi
and xi+1 we can calculate the width. Thus we can calculate the area of the
rectangle. If we sum the areas of all these rectangles that are in the interval
[a, b] then we get the approximate area under the graph. It should be clear
that the sum of these rectangles is less than the area under the curve.
1 get f from user
2 get a from user
3 get b from user
4 get n from user
5
6 set Area = 0
7 for Tmp ranges from a to b in steps of (b - a)/n do
8 set Area = Area + f(Tmp)*width
9 display Area
———
We can improve this approximation by using the second ordinate for the
value of the height, and following the same procedure. This approximates
the actual area under the curve from above. The average of these two values
will provide a much better approximation of the integral. Without repeating
the whole process the following idea achieves the same result.
25
Problem 1.23 Numeric integration by summing trapezia3
This problem is often posed as finding an approximation to the definite in-
tegral
Z b
f (x)dx.
a
Find the approximate area under the curve by calculating and summing the
areas under each trapezium bounded by the x-axis, by the two ordinates
xi –f (xi ), xi+1 –f (xi+1 ), and the line (xi , f (xi ))–(xi+1 , f (xi+1 )). Figure1.1
shows the ith trapezium. The function f (x) is given. and the bounds of the
fofx
fxpi
fxi
xi xpi
3
If you do not know Latin you might be inclined to spell the plural of trapezium as
trapeziums. Some people talk of trapezoids.
26
Chapter 2
(x + y)1 = 1x + 1y,
27
coefficients in various ways. Before doing this we look at a property that we
can derive from Equation 2.1 by setting both x and y to 1,
n
!
n
X n
2 = 1r 1n−r
r=0
r
So
n
!
X n
= 2n (2.2)
r=0
r
Columns
Rows r−1 r
n−1 C(n − 1, r − 1) C(n − 1, r)
n C(n, r − 1) C(n, r) = C(n − 1, r − 1) + C(n − 1, r)
triangle. It is named after Blaise Pascal. It has been studied for centuries
and is still the focus of vigorous attention.
The rows of Pascal’s triangle are conventionally enumerated starting
with row zero, and the numbers in odd rows are usually staggered rela-
tive to the numbers in even rows. A simple construction of the triangle
proceeds in the following manner. On the zeroth row, write only the num-
ber 1. Then, to construct the elements of following rows, add the num-
ber directly above and to the left with the number directly above and
to the right to find the new value. If either the number to the right or
left is not present, substitute a zero in its place. For example, the first
number in the first row is 0 + 1 = 1, whereas the numbers 1 and 3 in
the third row are added to produce the number 4 in the fourth row.”
28
n n n n n n n n n n n n
n 0 1 2 3 4 5 6 7 8 9 10 11
0 1
1 1 1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
5 1 5 10 10 5 1
6 1 6 15 20 15 6 1
7 1 7 21 35 35 21 7 1
8 1 8 28 56 70 56 28 8 1
9 1 9 36 84 126 126 84 36 9 1
10 1 10 45 120 210 252 210 120 45 10 1
11 1 11 55 165 330 462 462 330 165 55 11 1
29
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
By convention the first row is called ‘Row 0’. The sum of its coefficients
is 1. The sum of the coefficients of Row 4 is 15, in general the sum of the
binomials in row r is 2r .
n = f1 + f2 + . . . + fk
Algorithm
30
1 factors : array [1..1000] of numbers
2
1 set count = 0
2 set num = 1
3 repeat
4 count = fact (num)
5 set total = 0
6 for i ranges from 1 to count - 1 do
7 set total = total + factors(i)
8 if total = num then
9 begin block
10 set count = count + 1
11 display num
12 end block
13 set num = num + 1
14 until count = 15
31
———
3 set num_of_primes = 1
4 set primes[num_of_primes] = 2
5 set number_to_test = 3
6 repeat
7 set cnt = 1
8 while (num_to_test is not divisible by primes[cnt])
9 and (primes[cnt] < sqrt(num_to_test)) do
10 begin block
11 set cnt = cnt + 1
12 end block
13 if num_to_test is not divisible by primes[cnt] then
14 begin block
15 set num_of_primes = number_of_primes + 1
16 set primes[number_of_primes] = num
17 end block
18 set num_to_test = num_to_test + 1
19 until num_of_primes = 1000
20 for i ranges from 1 to 1000 do
21 display primes[i]
Problem 2.7 2
Find all prime numbers between Num1 and Num2.
32
How would we check to see if a number is prime or not? If a number
is divisible by any number other than 1 or itself, then that number is not
prime.
What do we know/have? We have already constructed several algorithms
to check whether a number is prime or not. All we need to know now is use
one of these algorithms to check each number between Num1 and Num2.
Algorithm in plain English
1 Get Num1, the lower boundary of the range
2 Get Num2, the upper boundary of the range
3 For each number between Num1 and Num2
4 1. Assume the number is prime
5 2. Test divisibility of the number by all potential factors
6 between 1 and the number itself
7 3. If the number is divisible by any of these numbers,
8 then it is not prime, otherwise it is prime
Algorithm in pseudocode using a repeat loop
1 repeat loop
2
3 get Num1 from user
4 get Num2 from user
5 for Num ranges from Num1 to Num2 do
6 begin block
7 set PFactor = 1
8 repeat
9 set PFactor = PFactor + 1
10 until (PFactor > square root of (Num))
11 or (Num divisible by PFactor)
12 if PFactor <= square root of (Num) then
13 display Num is not prime
14 else display Num is prime
15 end block
Algorithm in pseudocode using a while loop
1 while loop
2
3 get Num1 from user
4 get Num2 from user
5 for Num ranges from Num1 to Num2 do
6 begin block
7 set PFactor = 2
8 while (PFactor < square root of (Num)) and (Num not divisible by PFactor)
9 begin block
10 set PFactor = PFactor + 1
33
11 end block
12 if PFactor <= square root of (Num) then display Num is not prime
13 else display Num is prime
14 end block
———
34
Chapter 3
James Connan
jconnan@[Link]
35
3.3 What does a Computer Scientist do?
Computer Scientists use computers to solve problems.
Often new software needs to be developed to solve problems.
Software development requires problem solving and programming skills.
Example algorithms
Knitting pattern, e.g. cardigan, jersey.
Assembly Instructions, e.g. models, furniture, etc.
Recipe, e.g. pancake, pumpkin fritter, scones.
Pattern, e.g. dress, blouse, shirt, trousers, etc.
Musical score, e.g. for Beethoven’s Fifth Symphony, Beatles’ Ob-La-Di,
Ob-La-Da, etc.)
36
the elephant.’ makes no sense.
Logic rules check if the solution properly describes the process. If an
incorrect formula is used, or instructions are executed in incorrect order,
then the algorithm will fail.
37
1.1.2. turn on tap
1.1.3. wait until kettle full
1.1.4. turn off tap
1.2. switch on kettle
1.3. wait until boil
1.3.1. wait until kettle whistles
1.4. switch off kettle
2. put coffee in cup
2.1. open coffee jar
2.1.1. take jar off shelf
2.1.2. remove lid
2.2. measure coffee
2.3. put coffee in mug
2.4. close jar
2.4.1. replace lid
2.4.2. replace jar on shelf
3. add water to cup
3.1. pour water from kettle into mug until mug full
There are no now further sensible refinements that can be made to the
algorithm, so the algorithm is complete.
3. The steps are executed in the same order in which they are written.
38
3.10 Conditionals
Sequential algorithms allow us to solve many problems, but sometimes the
solution to a problem cannot be expressed in a sequential way. There may
also be instructions that we only want to execute under certain conditions.
In the coffee making algorithm, for example, if the kettle is already full we
do not need to fill it. The conditional statements we have are as follows:
if condition then
statement
The statement will only be executed if the condition holds.
if condition then
statement1
else
statement2
If the condition holds statement1 is executed and if it does not hold statement2
is executed.
case variable of
condition1: statement1
condition2: statement2
condition3: statement3
. . .
Case statements can be used to replace multiple if statements. If the variable
matches condition1 then statement1 will be executed. The same holds for
condition2, condition3, etc.
39
The value of variable is set to startvalue. The statement is then executed.
The value of variable is then incremented and statement is executed again.
This is repeated until the value of variable exceeds endvalue. At this stage
the loop exits. It is also possible to set startvalue higher than endvalue
and decrement variable each iteration until it reaches endvalue.
3.11.2 The while-loop
while condition do
statement
As long as the condition is valid the while-loop will continue executing
the statement. This means that statement must change something to allow
condition to become untrue or the loop will never terminate. There are
examples where it is desirable to have a loop that never terminates, but in
most cases this is not true.
3.11.3 The repeat-loop
repeat
statement
until condition
The statement will be executed until the condition is met. If the
statement does not change something to allow the condition to become true
then the loop will never terminate.
Some rules of thumb for loops
1. If we know exactly how many times we want a loop to be executed, it
is normally desirable to use a for-loop.
40
begin block
statement
statement
statement
end block
number [ ]
This array provides us with a variable, num, that has three ‘slots’ of type
number in which we can store values. These ‘slots’ are accessed by using
num[1], num[2] and num[3].
word: array[1..15] of character
word: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
number [ ]
This array provides us with 15 ‘slots’ of type character. They are accessed
by using word[1], word[2], ... , word[15].
num: array [5..8] of number
41
num: 5 6 7 8
number [ ]
This provides us with four ‘slots’ referenced using num[5], num[6], num[7]
and num[8].
set arr[2] = 7
This will store the value 7 in the position two of the array.
set arr[i] = 5
This will store the value 5 in position i of array arr. The value i must
be within the range of the array. That means that the value of i must be
between start and end.
set arr[i+1] = 5
Same as above, except that i+1 must now be within the range of the
array.
set arr[5] = arr[7]
This will set the value of the 5’th element of the array equal to the value
of the 7’th element.
set num = arr[3]
This will set the value of num equal to the value stored in position 3 of
array arr.
Arrays can have more than one dimensions. That is:
num : array [1..3][1..5] of number
num: 1 2 3 4 5
1
2
3
number [ ][ ]
This visualization is often used to make it easier to understand what multiple
—in this case 2—dimensional arrays are. We now have 15 ‘slots’ and each
‘slot’ is identified by two numbers. num[1,1] is the first element in the array
and num[3,5] is the last. There are now two indices1 that need to be used
1
If you don’t know Latin you might have called them indexes.
42
to reference each element and each must be within the boundaries defined
for its range. It is important to remember that the visualization above is
exactly that, just a visualization. The array could also have been visualized
as follows:
word: 1,1 1,2 1,3 1,4 1,5 2,1 2,2 2,3 2,4 2,5 3,1 3,2 3,3 3,4 3,5
number [ ][ ]
In fact this is the actual order that these elements are stored in memory
by just about every programming language except Fortran. It is known as
row-major order.
We are not restricted to two dimensions.
num : array [1..3][4..6][1..5][1..2][3..5] of number
This is a five dimensional array. We can store 3 × 3 × 5 × 2 × 3 = 270
elements in this array. Each element is referred to by 5 indices. Hence, num
[i,j,k,l,m] refers to one element in the array. Each of the indices i, j, k,
l, m must be within its defined range.
Arrays, combined with the looping structures we have already encoun-
tered, are very powerful tools to help us solve problems.
43
We can now call this procedure from another algorithm
1 get num from user
2 get power from user
3 pow (num,power)
We can also write this as a function
1 function pow(x,y)
2 begin block
3 set answer = 1
4 for i ranges from 1 to y do
5 set answer = answer * x
6 return set pow = answer
7 end block
The difference between a procedure and function is that a procedure can
only act on data/variables while a function can return a value.
1 get num from user
2 get power from user
3 set result = pow(x,y)
4 display result
3.14 Recursion
A function or procedure is said to be recursive when it calls itself. It is
possible to rewrite the power function above as a recursive function.
1 function pow(x,y)
2 begin block
3 if y = 0 then return set pow = 1
4 else return set pow = pow(x,y-1) * x
5 end block
When writing a recursive function the first thing to do is to find the base
case.
For example: Write an algorithm to work out n!
1! = 1,
2! = 1 × 2,
3! = 1 × 2 × 3,
4! = 1 × 2 × 3 × 4,
etc.
We can rewrite this as
1! = 1,
44
2! = 1! × 2,
3! = 2! × 3,
4! = 3! × 4,
etc.
In general n! = (n − 1)! × n
The base case is: when n = 1 then n! = 1. Thus
1 function factorial(n)
2 begin block
3 if n = 1 then return set factorial = 1
4 else return set factorial = factorial (n-1) x n
5 end block
Problem 3.1 Write a recursive algorithm that will add two num-
bers
45
1 get a from user
2 get b from user
3 get c from user
4
5 if a = 0 then
6 begin block
7 if c <> 0 then display x = -b/c
8 else
9 begin block
10 if b <> 0 then display x = 0
11 else display a=b=c=0
12 end block
13 end block
14 if a <> 0 then
15 begin block
16 if b^2 > -4ac then
17 begin block
18 display x = (-b + sqrt(b^2 - 4ac))/2a
19 display newline
20 display x = (-b - sqrt(b^2 - 4ac))/2a
21 display newline
22 end block
23 else display roots are not real
24 end block
———
Problem 3.4 Write a program that will find the sum of the first n
terms of the Taylor series for sin x
The Taylor-Maclaurin series for sin x which is given by
sin x = x − x3 /3! + x5 /5! − x7 /7! . . .
converges extremely rapidly. The error that is made using this estimation is
at most the size of the first term that has been left out such that the error
made when using only the terms shown above is at most |x9 /9!| which for
x = 1 is 0.0000027553, so taking the sum of the first four terms results in
six digits of accuracy. Since 32-bit floating point yields numbers with 7-digit
accuracy adding the next term, i.e., x9 /9! for x = 1, results in a value for
sin x with an error of at most 0.000000025048—that is seven accurate digits.
46
Problem 3.5 Write a program that will convert a temperature
from Celsius to Fahrenheit and vice versa.
1 set count = 0
2 repeat
3 set x = random
4 count = insert(num, count)
5 until count = 10
———
Problem 3.8 Write a program that will allow the user to calculate
the sum, dot product or cross product of two vectors.3
3
See [Link] product and [Link]
wiki/Dot product.
47
Problem 3.9 Create a list of 10 random integers in a tighter range
Now redesign your the algorithm to construct an array of 10 unique random
whole numbers in the range [A, B), for example, let the range be numbers
from the set {17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, represented by the
range [17, 29). Note that (1) the range excludes 29, and that there are enough
different numbers to enable the construction of at least 10 different numbers.
Algorithm
1 get volume from user
2 if volume > 120 then set cost = (volume-120)x1.25 + 40x1.15 + 80x0.90
3 if volume > 80 and volume <=120 then set cost = (volume-80)x1.15 + 80x0.90
4 if volume <= 80 then set cost = volume x 0.90
5 display volume water costs cost
48
Solution— Calculating leap years
The leap year status is determined by some if statements.
1 def isLeapyear(year):
2 if year % 400 == 0:
3 return True
4 if year % 100 == 0:
5 return False
6 if year % 4 == 0:
7 return True
8 else:
9 return False
A shorter version is:
1 def isLeapyear(year):
2 return year % 400 == 0 or year % 4 == 0 and year % 100 != 0
———
49
Solution— Day of the week
One start by counting the difference in days by calculating the number of
years, months and days from a base date for which you know the day of the
week, and then simply getting the day of the week using modulo 7. We call
this number the daydate.
It does not matter what the starting date is, if the days counted are
correct then calculate daydate for today and get today = daydate % 7. Since
we know what day of the week today is, henceforth today represents that
day of the week. Suppose today is a Tuesday, and today= 3, then 3 is a
Tuesday, 4 is a Wednesday, 5 is a Thursday, 6 is a Friday, 0 is a Saturday, 1
is a Sunday, 0 is a Monday. Now we calculate daydate, given the parameters
year, month, day
1 def daydate(year, month, day):
2 mdays = [30 + (m + m//8 ) % 2 for m in range(1, 13)]
3 mdays[1] = 28 + int(isLeapyear(year))
4 days = 1
5 mdays = [0]+mdays[:-1]
6
7 for m in range(month):
8 days += mdays[m]
9 mdays[m] = days
10
11 days = day + mdays[month-1]
12 years = year - 1600 # Our base date is 1601-01-01
13 days += years * 365
14 leapcenturies = ((years - 1) // 100 - 16)//4 + 1 # Add leap years
15 days += leapcenturies
16 weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
17 return weekdays[days % 7]
———
50
Solution— The Gauss 1812 algorithm for calculating Easter
The algorithm of Gauss for calculating Easter
1
2 a = year %19
3 b = year % 4
4 c = year % 7
5 k = floor (year/100)
6 p = floor ((13 + 8k)/25)
7 q = floor (k/4)
8 M = (15 p + k q) % 30
9 N = (4 + k q) % 7
10 d = (19a + M) % 30
11 e = (2b + 4c + 6d + N) % 7
12 Gregorian Easter is 22 + d + e March or d + e 9 April
13 if d = 29 and e = 6, replace 26 April with 19 April
14 if d = 28, e = 6, and (11M + 11) % 30 < 19, replace 25 April with 18 April
15 For the Julian Easter in the Julian calendar M = 15 and N = 6 (k, p, and q are unnecessary)
———
Solution— Easter in a spreadsheet
The following spreadsheet formula calculates the date of Easter Sunday.
1 =ROUND(DATE(A1,4,1)/7 + MOD(19*MOD(A1,19) - 7, 30)*14%, 0)*7 - 6
———
Problem 3.16 Birthdays on the same day
Suppose that a room is occupied by some people. If there is only one person
in the room nobody will share his birthday so the probability q that there is
365
nobody to share his birthday is q1 = 365 = 1. When there are two people in
the room the probability that no two people share a birthday becomes q2 =
365×364
3652
= 0.9972602739.4 In general if there are n people in the room the
probability that no pair of people share a birthday becomes
Qn
−r+1
r=1 365
qn = .
365n
The problem is to discover how many people must be in the room for the
probability that there are two people that have a birthday on the same day
are in the room, i.e. find an n such that p = 1 − qn > 0.5.
Solution— Birthdays on the same day
Simply calculate the running fraction qn to discover at which n it becomes
less that a half. ———
4
Notice how we write the repeating decimal 0.99 72602739 72602739 . . ..
51
Chapter 4
4.1
Problem 4.1 S = N
P
r=1 r
Suppose that the integer N is given. Construct an algorithm to add all the
integers from 1 up to and including N , i.e. calculate the sum S,
N
X
S= r = 1 + 2 + . . . + N.
r=1
Solution— S = N
P
r=1 r
We first initialize a variable called S to zero and subsequently add the values
of r running from 1 to N one by one.
1 N = 10
2 S = 0
3 for r in range(1, N+1):
4 S += r
5 print ("Sum of integers from 1 to %d is %d" % (N, total))
A much tidier solution, more in the spirit of Python style, is:
1 N = 10; S = sum([r for r in range(1, N+1)])
The for r in range(1,N+1) generates each r which is then agglomerated
into a list by the surrounding brackets [. . . ]. The function sum is built in,
and yields the sum of the numbers in a list.
52
If you were Carl-Fried Gauss, at the age of about ten years, you would
no doubt have noticed that the sums
1, 2, . . . , N − 1, N
+
N, N − 1, . . . , 2, 1
add up to
N + 1, N + 1, . . . , N + 1,
and that half of this is the required sum, and further you would have seen
that there are N of these N + 1 terms and you have given the answer in a
flash as
N × (N + 1)
.
2
Gauss would have programmed the requested result as
1 N = 10; S = N*(N+1)/2
Notice that despite the division by two, the result is a whole number.
———
53
1 17
2 23
3 29
4 31
5 37
6 41
7 47
54
which eventually turns the argument into 1 which will then be added to 2,
. . . until finally N is added. So, first test if N is 1 and otherwise return
N + add(N − 1).
1 def add(N):
2 if N == 1:
3 return N
4 else:
5 return N + add(N-1)
6
7 print (add(10))
———
55
The function returns zero when the value of B is zero, and returns the value
of A when B is one, otherwise the function returns mult(A, B - 1) + A. We
have multiplied without using addition. The Python code follows
1 def mult (A, B):
2 if B == 0:
3 return 0
4 elif B == 1:
5 return A
6 else:
7 return add(mult(A, dec(B)), A)
8
9 print (mult(3,7))
———
9 print (power(3,7))
———
56
Solution— Using logarithms to calculate exponents
The simple answer is to use logarithms. Since log AB = B log A, we write
AB = exp(B log A) and get the result quite quickly. The snag is that the
accuracy of the log and exp is usually limited on computers to about 7
digits for single precision or to 18 digits for double precision—Python uses
double precision reals. This may be a problem when doing exponentiation
in cryptographic calculations where numbers with precisions of 256 or 512
binary digits are used.2 We give a version of this function
1 def power (A, B):
2 from math import log, exp
3 return exp(B*log(A))
4
5 print (power(3, 100))
Python has a built-in operator for exponentiation, so we could simply have
programmed
1 print (3**100)
Python also has a built-in function for exponentiation, so the following is
also a good way
1 print (pow(3,100))
———
57
multiplications by
A2 = A × A,
A4 = A2 × A2 ,
A8 = A4 × A4 ,
A16 = A8 × A8 ,
A32 = A16 × A16 .
58
Table 4.1: Number of multiplications needed for An . Note: Table has not
been checked for correctness.
Power of Number of
A multiplications How
A2 1 A×A
A3 2 A×A×A
A4 2 A2 × A2
A5 3 A2 × A2 × A
A6 3 A2 × A2 × A2
A7 2 A2 × A2 × A3
A8 3 A4 × A4
A9 4 A4 × A4 × A
A10 4 A4 × A4 × A2
A11 5 A4 × A4 × A3
A12 4 A4 × A4 × A4
A13 4 A4 × A4 × A5
..
. A4 × A4 × A7
A16 4 A8 × A8
A32 5 A16 × A16
A33 6 A32 × A
A34 6 A32 × A2
59
Solution— N ! recursively
When the argument of factorial(N) is 1 or 0 return a 1 otherwise the
factorial of N is N * factorial(N-1).
1 def factorial (N):
2 if N < 2:
3 return 1
4 else:
5 return N * factorial(N-1)
6
7 print (factorial(6))
———
Solution— N ! iteratively
The non-recursive solution of N ! applies the definition directly. Build the
product that we have named product starting from 1. Multiply this by each
value r ∈ [2..N ] ≡ [2..N + 1).
1 def factorial (N):
2 product = 1
3 if N > 1:
4 for r in range(2, N+1):
5 product *= r
6 return product
7
8 print (factorial(6))
In Line 5 the “times and becomes” operator “product *= r” requires less
typing than “product = product * r”, so it is preferred. ———
60
1 def factorial (n):
2 product = 1
3 if n > 1:
4 for r in range(2, n+1):
5 product *= r
6 return product
7
8 def binom(n, r):
9 return factorial(n)/(factorial(r)*factorial(n-r))
10
11 print (binom(52,4))
———
nr = n × n − 1 × . . . n − r + 1
61
6
7 return binom
———
The ultimate Pythonic way to write the factorial function is to use a gen-
erator. The generator yields values one by one, discarding the previous
values.
62
numbers. Starting with 0 and 1 next number in the sequence is the sum of
the previous two.
63
Problem 4.16 A generator for Fibonacci numbers
Program a generator version of Fibonacci based on the iterative solution.
1 def sort(L):
2 if not L:
3 return L
4 it, rest = L[0], L[1:]
5 smaller = [item for item in rest if item < it]
6 greaterEqual = [item for item in rest if item >= it]
7 return sort(smaller) + [it] + sort(greaterEqual)
8
9 from random import random
10
11 N = 100
12 L = [int(random()*N) for x in range(N)]
13 print (sort(L))
64
———
65
8
9 hanoi (3, "From", "Help", "To")
———
Polynomials are interesting for many reasons. They form the basis of our
number system. They may be used to approximate functions as accurately
as needed. Polynomials are useful because they are easy to differentiate and
integrate. They play an important role in algebra.
we get a different view of the same polynomial and in this form putting
the variable x = 10 and restricting the coefficients to the decimal digits
di ∈ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, the polynomial
dn dn−1 . . . d2 d1 d0
66
9 from time import time
10 a = [1, 4, 6, 4, 1]
11 n = 4
12 for x in range(0, 11):
13 start = time()
14 print("P%d(%f) = %f, took %.5f s." % (n, x, P(n,a,x), time() - start))
Another way of writing the polynomial is to number the coefficients differ-
ently as
Rewrite the code corresponding to the array written with the coefficient of
the xn first. ———
67
4 pol = a[k] + pol*x
5 return pol
6
7 from time import time
8 a = [1, 4, 6, 4, 1]
9 n = 4
10 for x in range(0, 11):
11 start = time()
12 print("P%d(%f) = %f, took %.5f s." % (n, x, P(n,a,x), time() - start))
———
68
Problem 4.23 Multiplication of polynomials
Given two polynomials, Pn (x) and Qn (x) write a programme to multiply
them. i.e. write code to produce
Rn (x) = Pn (x) × Qn (x).
Problem 4.24 Division of polynomials
Given two polynomials, Pn (x) and Qn (x) write a programme to divide them.
i.e. write code to produce
Rn (x) = Pn (x)/Qn (x).
Problem 4.25 Polynomials representing numbers
The polynomial over the variable b with coefficients conveniently called digits
di ∈ [0..b) = {0, 1, ..., b − 1}, may be used to represent any number in base b
Pn (b) = dn bn + dn−1 bn−1 + . . . + d2 b2 + d1 b + d0
Write code to convert a number Pn (b) in base b to a number Qn (r) in base
r with digits called si ∈ [0..c) = {0, 1, . . . , c − 1}. with the same value. The
problem is to convert the polynomial P
P = dn bn + dn−1 bn−1 + . . . + d2 b2 + d1 b + d0
into the polynomial Q
Q = sn rn + sn−1 rn−1 + . . . + s2 r2 + s1 r + s0 ,
so that P = Q.
Solution— Polynomials representing numbers
This turns out to be easy. We are given the polynomial P and its coefficients
and are asked to extract the “digits”, si from it. Since P = Q, we can do
arithmetic on Q as the proxy of P , so, first copy Q into P . Consider Q,
Q = sn rn + sn−1 rn−1 + . . . + s2 r2 + s1 r + s0 ,
All the terms of Q excepting s0 are divisible by r, so it is clear that we can
calculate s0 by
s0 = Q mod r
and then subtract—the digit—s0 from Q, divide the result with r and replace
Q with the result
Q − s[0]
Q= = sn rn−1 + sn−1 rn−2 + . . . + s2 r + s1 .
r
In Python we do this with the two lines
69
1 s[0] = Q % r
2 Q //= r
The steps start repeating. At this stage, all the terms of Q excepting s1 are
divisible by r, so it is calculated
s1 = Q mod r
and then subtract the digit s1 from Q, divide the result with r and replace
Q with that
Q − s[1]
Q= = sn rn−2 + sn−1 rn−3 + . . . + s3 r + s2 .
r
In Python we do this with the two lines
1 s[1] = Q % r
2 Q //= r
The process continues while Q 6= 0. The code becomes
1 s = [0]*(n + 1)
2 i = 0
3 while Q != 0:
4 s[i] = Q % r
5 Q //= r
6 i += 1
———
70
Chapter 5
Problem 5.4 Find the sum of the numeric keys in a path from the
root to a given node in a binary search tree
Problem 5.5 Find an item in a sorted list that has been cut once
Suppose you have a sorted list of length n that has been rotated by k places.
71
Problem 5.9 Reverse a doubly-linked list
Problem 5.11 Given the time give the angle in radians between
the short hand and the long hand of an analogue clock
Problem 5.17 Make a new set from the numbers in two sets
Given a set of A of 100 integers and another set of B of 1000000 integers,
form a new set that contains all the numbers in A ∪ B.
Problem 5.18 Find the numbers in two sets that are not common
to both sets
Given a set of 100 integers and another set of 1000000 integers. This set is
called the symmetric difference.
72
Problem 5.21 Is a given undirected graph a tree or not?
Problem 5.22 Find common data from two very large files that do
not fit into memory simultaneously
Problem 5.25 Use command line code to get the common data
from three files
Problem 5.26 You have a jar with balls uniquely numbered from
1 to 100. You have removed 99 of these balls. What is the number
on the remaining ball?
The ancient Babylonians had a fast formula for calculating the square root
of any number. This algorithm was described by Heron of Alexandria in his
book called Metrica near the dawn of the √ Christian era about 60 ACE.
Apply Heron’s formula to calculate A:
“(1) Start with a guess of the root r.
(2) If r2 is close enough to A, then use r as the square root.
(3) Otherwise re-estimate r using the average of r and A/r, i.e.,
r + A/r
r←
2
.
(4) Repeat from step (2).”
73
√
In books on numerical mathematics Heron’s formula to calculate A is
often ascribed to Newton and is described using the series {r0 , r1 , r2 , . . .}
that converges to the root.
Initialize r0 = 1, and
iterate rn+1 = (rn + A/rn )/2
2
until |rn+1 −A| < ε where ε is an arbitrary small positive number. Note that
careful application of this formula in a program does not require subscripts.
Problem 5.28
Problem 5.35 Find the largest and and second largest elements in
a list of integers.
74
Problem 5.38 Convert decimal number to Roman number.
Problem 5.46 Check if two binary trees mirror one another ex-
actly
75
Chapter 6
76
Bibliography
77
Appendix A
Prefix Symbol 1000m 10n Decimal Short scale Long scale Since
yotta Y 10008 1024 1000000000000000000000000 Septillion Quadrillion 1991
zetta Z 10007 1021 1000000000000000000000 Sextillion Trilliard 1991
exa E 10006 1018 1000000000000000000 Quintillion Trillion 1975
peta P 10005 1015 1000000000000000 Quadrillion Billiard 1975
tera T 10004 1012 1000000000000 Trillion Billion 1960
giga G 10003 109 1000000000 Billion Milliard 1960
mega M 10002 106 1000000 Million 1960
kilo k 10001 103 1000 Thousand 1795
hecto h 10002/3 102 100 Hundred 1795
deca da 10001/3 101 10 Ten 1795
10000 100 1 One —
deci d 1000−1/3 10−1 0.1 Tenth 1795
centi c 1000−2/3 10−2 0.01 Hundredth 1795
milli m 1000−1 10−3 0.001 Thousandth 1795
micro 1000−2 10−6 0.000001 Millionth 1960
nano n 1000−3 10−9 0.000000001 Billionth Milliardth 1960
pico p 1000−4 10−12 0.000000000001 Trillionth Billionth 1960
femto f 1000−5 10−15 0.000000000000001 Quadrillionth Billiardth 1964
atto a 1000−6 10−18 0.000000000000000001 Quintillionth Trillionth 1964
zepto z 1000−7 10−21 0.000000000000000000001 Sextillionth Trilliardth 1991
yocto y 1000−8 10−24 0.000000000000000000000001 Septillionth Quadrillionth 1991
78
Appendix B
Using simplegui
79
Contents
80
6 Linux command line interface problems 76
B Using simplegui 79
81