You are on page 1of 5

De grootste gemene deler

Bart Demoen
KU Leuven

Abstract
Bij dit onderwerp vliegt met dikwijls direct naar het algoritme van
Euclides. Beter is het om te vertrekken van de definitie van de grootste
gemene deler van twee getallen, en die letterlijk te implementeren. Dat
maakt de correctheid simpel in te zien. Daarna kunnen overwegingen
komen als efficiëntie ...

1 Voorkennis, leerwinst, beperking


1.1 Voorkennis i.v.m. programmeren
Simpele aritmetiek, toekenning, herhaling.

1.2 Andere voorkennis


Voor de meer efficiënte programma’s, modulo rekenen.

1.3 Leerwinst i.v.m. programmeren


Afhankelijk van wat al gekend was, en hoever deze module gevolgd wordt:

• een specificatie (definitie) omzetten in een programma


• redeneren over correctheid (niet noodzakelijk bewijzen !)

• recursieve functies

1.4 Beperking
De voorbeelden werken enkel met getallen. Inzien dat het algoritme van Euclides
correct is, vergt misschien meer wiskunde dan in de doelgroep aanwezig is ?

1
1.5 Tips
In de tekst wordt geen aandacht geschonken aan de ontwikkeling van de functie
deelt(a,b) die bepaalt of a een deler is van b. Dat kan vooraf gedaan worden, of
als opdracht gegeven worden.
In hoeverre dit gebruikt wordt als uitgewerkt voorbeeld gepresenteerd door de
leraar, of als doe-het-zelf door de leerling: de leraar beslist.

2 De grootste gemene deler


We vertrekken van een definitie van grootst gemene deler en proberen die slaafs
te implementeren:

de grootste gemene deler van getallen a en b is het grootste getal dat


een deler is van a en van b

Het gaat hier om natuurlijke getallen.


Vóór we beginnen te implementeren ... we zoeken een grootste. We moeten dus
best zeker zijn dat

die grootste bestaat


Bijvoorbeeld: het grootste priemgetal bestaat niet.
Een tweede overweging: bij het zoeken naar iets is het nuttig te weten waar het
ongeveer ligt, een gebied waarvan je zeker bent dat het iets daarin ligt. Dat
gebied mag groter dan nodig zijn, maar mag niet te klein zijn. Vermits we hier
een deler d zoeken weten we zeker dat d ≥ 1: dat geeft ons een ondergrens van
het interval waarin d ligt. Wat komt in aanmerking als bovengrens voor de ggd
van a en b ? Hier wat voorstellen
Lager dan min(a, b) mag niet, want de ggd(12, 24) is gelijk aan 12 en dat is
min(12, 24).

• a+b
• max(a, b): het maximum van a en b

• min(a, b): het minimum van a en b

Een deler kan niet groter zijn dan die grootheden hierboven, dus zijn het boven-
grenzen die garanderen dat je zoekproces stopt. Dus: systematisch zoeken in
één van de intervallen
• [1, a + b]
• [1, max(a, b)]: het maximum van a en b

• [1, min(a, b)]: het minimum van a en b

2
levert een ggd van a en b op. Die 1 mag je niet door 2 vervangen, want ggd(7, 13)
is gelijk aan 1.
Vermits min(a, b) ≤ max(a, b) ≤ a + b is [1, min(a, b)] het kleinste interval,
maar die andere kunnen ook een correct resultaat geven.
Hier zijn alvast twee programma’s die bovenstaande overwegingen gebruiken:

Listing 1: Eerste versie van ggd (ggd.py)


1 def ggd ( a , b ) :
2 g = 1
3 f o r i in range ( 2 ,min( a , b ) + 1 ) :
4 i f d e e l t ( i , a ) and d e e l t ( i , b ) :
5 g = i
6 return ( g )
7
8 def d e e l t ( x , y ) :
9 return ( y == ( y // x ) ∗ x )

Listing 2: Tweede versie van ggd (ggd.py)


59 def ggd ( a , b ) :
60 f o r i in range (min( a , b ) , 0 , − 1 ) :
61 i f d e e l t ( i , a ) and d e e l t ( i , b ) :
62 return ( i )

Deze versies hebben gemeen dat de for-lus verlaten wordt met een return. Het
kan ook anders: zie hieronder.

Listing 3: De eerste versie met while i.p.v. for (ggd.py)


64 def ggd ( a , b ) :
65 g = 1
66 while g =< min( a , b ) and not ( d e e l t ( g , a ) and d e e l t ( g , b ) ) :
67 g += 1
68 return ( g )

3
3 Opdrachten
• beredeneer/argumenteer de correctheid van de programma’s die je tot nu
toe zag; geef ook aandacht aan het aspect: het programma eindigt1
• gebruik eigenschappen van ggd uit de wiskunde, zoals
– als a ≤ b dan is ggd(a, b) is gelijk aan ggd(a, b − a)
– ggd(a, b) is gelijk aan ggd(b, a)
– als a ≤ b dan is ggd(a, b) is gelijk aan ggd(a, b mod a)
– ggd(a, a) is gelijk aan a
– als d een deler is van a en b, dan is ggd(a, b) gelijk aan d∗ggd(a//d, b//d)
– ggd(0, a) is gelijk aan a als a > 0

om alternatieve functies voor ggd te schrijven


• geef argumenten waarom het ene programma slechter/beter zou zijn dan
het ander
• zoek op: algoritme van Euclides; heb je het heruitgevonden ?

1 als de notie van eindigheid nog niet besproken is, doe het nu

4
4 Varianten
Listing 4: Versies van ggd (ggd.py)
11 def ggdv1 ( a , b ) :
12 while a != b :
13 if (a > b):
14 a = a − b
15 else :
16 b = b − a
17 return ( a )
18
19 def g g d v 1 r e c ( a , b ) :
20 i f ( a == b ) :
21 return ( a )
22 if (a > b):
23 return ( g g d v 1 r e c ( a−b , b ) )
24 else :
25 return ( g g d v 1 r e c ( b−a , a ) )
26
27 def ggdv2 ( a , b ) :
28 while a ∗b != 0 :
29 if (a > b):
30 a = a%b
31 else :
32 b = b%a
33 return ( a+b )
34
35 def ggdv3 ( a , b ) :
36 ggd , i = 1 , 2
37 while i <= min( a , b ) :
38 i f ( a%i == 0 ) and ( b%i == 0 ) :
39 a = a // i
40 b = b// i
41 ggdv ∗= i
42 else :
43 i += 1
44 return ( ggd )
45
46 def ggdv4 ( a , b ) :
47 return ( g g d v 4 b i s ( 2 , a , b ) )
48
49 def g g d v 4 b i s ( i , a , b ) :
50 i f ( i > min( a , b ) ) :
51 return ( 1 )
52 i f ( a%i == 0 ) and ( b%i == 0 ) :
53 a = a // i
54 b = b// i
55 return ( i ∗ g g d v 4 b i s ( i , a , b ) )
56 else :
57 return ( g g d v 4 b i s ( i +1 ,a , b ) )

You might also like