Ga naar hoofdinhoud

Opgaven

Wat je geleerd hebt

In dit hoofdstuk is het volgende besproken:

  • Wat loops zijn
  • while loops
  • for loops
  • Eindeloze loops
  • Loop controle via else, break, en continue
  • Geneste loops
  • De loop-en-een-half
  • Slim zijn met loops

Omdat loops geweldig belangrijk zijn en studenten er vaak problemen mee hebben, geef ik hierbij een groot aantal opgaven. Ik raad je aan ze allemaal te maken. Je zult er veel van leren.

Opgave 1

Schrijf een programma dat de gebruiker een getal laat ingeven. Het programma geeft de tafel van vermenigvuldiging van het getal voor 1 tot en met 10.

Voorbeeld

Invoer:

12

Uitvoer:

1 * 12 = 12
2 * 12 = 24
3 * 12 = 36
4 * 12 = 48
5 * 12 = 60
6 * 12 = 72
7 * 12 = 84
8 * 12 = 96
9 * 12 = 108
10 * 12 = 120

Opgave 2

Als je de vorige opgave met een for loop hebt gedaan, doe hem dan nogmaals met een while loop. Als je hem met een while loop hebt gedaan, doe hem dan nogmaals met een for loop. Als je hem gedaan hebt zonder loop, dan moet je je schamen.

Opgave 3

Schrijf een programma dat de gebruiker vraagt om 10 getallen, en dan de grootste, de kleinste, en het aantal deelbaar door 3 afdrukt. Gebruik het algoritme dat eerder in dit hoofdstuk beschreven is.

Voorbeeld

Invoer:

656
452
555
726
924
863
939
831
616
406

Uitvoer:

grootste: 939
kleinste: 406
drievouden: 5

Opgave 4

"99 bottles of beer" is a traditioneel liedje gezongen in Amerika en Canada. Het wordt vaak gezongen op lange reizen omdat het gemakkelijk te onthouden en mee te zingen is, en lang duurt. In vertaling is de tekst:

99 flesjes met bier op de muur, 99 flesjes met bier.
Open er een, drink hem meteen, 98 flesjes met bier op de muur.

Deze tekst wordt herhaald, steeds met één flesje minder. Het lied is voorbij als de zangers nul bereiken.

Schrijf een programma dat het hele lied afdrukt (ik raad je aan te beginnen met niet meer dan 10 flesjes). Kijk uit dat je je loop niet eindeloos maakt. Zorg er ook voor dat je het juiste meervoud voor het woord “flesje” gebruikt.

Opgave 5

De rij van Fibonacci is genoemd naar Leonardo van Pisa, bijgenaamd Fibonacci ("zoon van Bonaccio", namelijk van Guglielmo dei Bonaccio). De rij begint met 0 en 1 en vervolgens is elk volgende element van de rij steeds de som van de twee voorgaande elementen. De eerste elementen van de rij zijn dan als volgt:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

Schrijf een programma dat de Fibonacci reeks afdrukt totdat de getallen groter dan 1000 zijn.

Opgave 6

Schrijf een programma dat vraagt om twee woorden. Druk alle letters af die de woorden gemeen hebben. Je mag hoofletters beschouwen als verschillend van kleine letters, maar iedere letter die je rapporteert, mag slechts één keer gerapporteerd worden (bijvoorbeeld, de strings “een” en “peer” hebben slechts één letter gemeen, namelijk de letter “e”).

Hint: Sla de letters die de woorden gemeen hebben op in een derde string, en als je een letter vindt die beide woorden gemeen hebben, test je of de letter al in de derde string staat alvorens je hem rapporteert.

Opgave 7

Schrijf een programma dat π\pi benadert door middel van toevalsgetallen, als volgt: Neem een vierkant van 1 bij 1. Als je een dart in dat vierkant gooit op een willekeurige plek, is de waarschijnlijkheid dat de afstand van de dart tot de linkeronderhoek van het vierkant kleiner dan 1 is gelijk aan π/4\pi/4.

pi

Om dat in te zien, bedenk dat de oppervlakte van een cirkel met straal 1 π\pi is, dus de oppervlakte van een kwart cirkel is π/4\pi/4. Als dus een dart op een willekeurig punt in het vierkant landt, is de waarschijnlijkheid dat die dart in de kwart cirkel landt π/4\pi/4. Als je nn darts in het vierkant werpt, en mm ervan landen in de kwart cirkel, dan benadert 4m/n4m/n de waarde π\pi als nn voldoende groot is.

Het programma heeft een constante die aangeeft hoeveel darts gesimuleerd moeten worden. Het toont een benadering van π\pi door het werpen van zoveel darts te simuleren. De afstand van een punt (x,y)(x, y) tot de linkeronderhoek kun je berekenen als x2+y2\sqrt{x^2 + y^2}.

Opgave 8

Schrijf een programma dat een toevalsgetal neemt tussen 1 en 1000 (je kunt randint() daarvoor gebruiken). Het programma vraagt de gebruiker het getal te raden. Na iedere poging van de gebruiker zegt het programma "Lager" als het te raden getal lager is, "Hoger" als het te raden getal hoger is, of "Je hebt het geraden!" als het getal correct is. Het programma eindigt met afdrukken hoeveel pogingen de gebruiker nodig had om het getal te raden. Voor test-doeleinden kan het slim zijn om het te raden getal op het scherm te laten zien, totdat je zeker weet dat het programma goed werkt.

Opgave 9

Schrijf een programma dat het omgekeerde is van het vorige: nu neemt de gebruiker een getal in gedachten en de computer probeert het te raden. Op de pogingen van de computer moet de gebruiker antwoorden met een letter: "L" voor lager als het te raden getal lager is, "H" voor hoger als het te raden getal hoger is, en "C" voor correct (je kunt de getLetter() functie van pcinput hiervoor gebruiken). Als de computer het getal geraden heeft, drukt het af hoeveel pogingen er nodig waren. Zorg ervoor dat de computer ook herkent dat er geen mogelijk antwoord is (misschien omdat de gebruiker een vergissing heeft gemaakt, of omdat de gebruiker de computer in het ootje probeerde te nemen). Een slim programma hoeft hoogstens tien keer te raden.

Opgave 10

Een priemgetal is een positief geheel getal dat deelbaar is door precies twee verschillende getallen, namelijk 1 en het priemgetal zelf. Het laagste en enige even priemgetal is 2. De eerste 10 priemgetallen zijn

2, 3, 5, 7, 11, 13, 17, 19, 23, 29

Schrijf een programma dat de gebruiker om een getal vraagt en dan afdrukt of het getal een priemgetal is.

Hint: Test in een loop alle mogelijke delers van het getal. In deze loop kun je concluderen dat een getal geen priemgetal is zodra je een deler (anders dan 1 of het getal zelf) hebt gevonden. Je kunt echter alleen na afloop van de loop constateren dat het getal een priemgetal is, want dan heb je pas alle mogelijke delers getest.

Opgave 11

Schrijf een programma dat een tafel van vermenigvuldiging afdrukt voor de cijfers 1 tot en met een zeker getal num (je mag voor de output aannemen dat num één cijfer is). Een tafel van vermenigvuldiging voor 1 tot en met 3 ziet er als volgt uit:

  | 1 2 3
=========
1 | 1 2 3
2 | 2 4 6
3 | 3 6 9

Dus de cellen van de matrix bevatten het label van de kolom vermenigvuldigd met het label van de rij.

Opgave 12

Schrijf een programma dat alle gehele getallen tussen 1 en 100 afdrukt die geschreven kunnen worden als de som van twee kwadraten. De uitvoer is een lijst van regels van de vorm z = x**2 + y**2, bijvoorbeeld, 58 = 3**2 + 7**2. Als een getal twee keer wordt afgedrukt met verschillende manieren om het te schrijven als de som van twee kwadraten, dan is dat acceptabel (dit kan gelden voor 50, 65, en 85).

Opgave 13

Je gooit een aantal dobbelstenen één voor één na elkaar. Hoe groot is de kans dat de waarde van elke dobbelsteen groter of gelijk is dan de waarde van de vorige dobbelsteen?

Als we bijvoorbeeld met 5 dobbelstenen gooien, dan is

1, 1, 4, 4, 6

een niet-dalende reeks worpen, en is

1, 1, 4, 3, 6

dat niet.

Bepaal deze waarschijnlijkheid door een groot aantal pogingen te simuleren.

Opgave 14

A, B, C, en D zijn vier verschillende cijfers. Het getal DCBA is gelijk aan 4 keer het getal ABCD. Wat zijn de cijfers?

Opmerking

Om ABCD en DCBA conventionele schrijfwijzes van getallen te laten zijn, mag noch A, noch D nul zijn.

Opgave 15

Volgens een oude puzzel zijn vijf piraten en hun aap gestrand op een eiland. Gedurende de dag verzamelen ze kokosnoten, die ze op een grote stapel leggen. Wanneer de nacht valt gaan ze slapen.

Midden in de nacht wordt de eerste piraat wakker. Hij vertrouwt zijn makkers niet, dus hij verdeelt de stapel kokosnoten in vijf gelijke delen, neemt wat hij aanneemt dat zijn deel is, en verstopt dat. Hij houdt één kokosnoot over, en die geeft hij aan de aap. Dan valt hij weer in slaap.

Een uur later wordt de tweede piraat wakker. Hij handelt net als de eerste piraat: hij verdeelt de stapel in vijf gelijke delen, neemt wat hij denkt dat zijn deel is, en verstopt dat. Ook hij houdt een kokosnoot over die hij aan de aap geeft. Dan valt hij weer in slaap.

Hetzelfde gebeurt de andere drie piraten: één voor één worden ze wakker, verdelen de stapel, geven een kokosnoot aan de aap, verstoppen hun deel, en gaan weer slapen.

In de ochtend worden ze allemaal wakker. Ze verdelen eerlijk wat er van de stapel kokosnoten over is. Dat laat één kokosnoot over, en die gaat naar de aap.

De vraag is: wat is het kleinste aantal kokosnoten dat er op de originele stapel kan hebben gelegen?

Schrijf een Python programma dat de puzzel oplost. Het is nog beter als je het kunt oplossen voor een willekeurig aantal piraten.

Opgave 16

Beschouw de driehoek die hier beneden is weergegeven. Deze driehoek bevat een kolonie Driehoekkruipers, en een Verslinder van Driehoekkruipers. De Verslinder zit in punt D. Alle Driehoekkuipers worden geboren in punt A. Een Driehoekkruiper die bij punt D aankomt, wordt opgegeten.

driehoek

Iedere dag kruipt iedere Driehoekkruiper over een van de lijnen in de driehoek naar een willekeurig bepaald punt, maar niet naar het punt waar hij de dag ervoor was. Deze beweging kost één dag. Bijvoorbeeld, een Driehoekkruiper die net geboren is in punt A, zal op de eerste dag van zijn leven kruipen naar B, C, of D. Als hij naar B gaat, zal hij de volgende dag naar C of D gaan, maar niet terug naar A. Als hij naar C gaat, zal hij de volgende dag naar B of D gaan, maar niet terug naar A. Als hij naar D gaat, wordt hij opgegeten.

De waarschijnlijkheid dat een Driehoekkruiper op de eerste dag onmiddellijk naar D gaat is 1/31/3, en dan leeft hij dus maar één dag. In principe kan een Driehoekkruiper iedere willekeurige leeftijd bereiken, hoe hoog ook, door in cirkels te bewegen van A naar B naar C en terug naar A (of tegen de klok in, van A naar C naar B en terug naar A). Maar omdat hij iedere dag na de eerste per toeval kiest voor een volgend punt, is iedere dag na de eerste de waarschijnlijkheid dat hij wordt opgegeten 1/21/2.

Schrijf een programma dat een benadering berekent van de gemiddelde leeftijd waarop een Driehoekkruiper overlijdt. Doe dit door de simulatie van 100.000 Driehoekkruipers, waarbij je alle dagen dat ze leven optelt, en het totaal deelt door 100.000.

Hint

Er zijn twee manieren waarop je dit programma kunt aanpakken: ofwel je simuleert het gedrag van één Driehoekkruiper en herhaalt dat 100.000 keer, ofwel je start met een populatie van 100.000 Driehoekkruipers in punt A, en verdeelt die over variabelen die bijhouden hoeveel Driehoekkruipers in ieder punt zitten op iedere dag, waarbij je ook bijhoudt van welk punt ze komen (overblijvende Driehoekkruipers worden aan een toevallig naburig punt toebedeeld). De eerste methode is kort en eenvoudig maar traag, de tweede is lang en complex maar snel. Je mag zelf kiezen welke methode je wilt gebruiken.

Hint

Begin niet met 100.000 Driehoekkruipers voor je eerste pogingen. Start met 1000 (of misschien met slechts 1), en probeer het pas met 100.000 als je weet dat je programma min of meer klaar is. Testen gaat veel sneller met minder Driehoekkruipers. 1000 Driehoekkruipers kunnen worden gesimuleerd in minder dan een seconde, dus als je programma meer tijd nodig heeft, heb je waarschijnlijk een eindeloze loop gemaakt.

Hint

Ik zal niet te specifiek zijn, maar het antwoord is ergens tussen de 1 en 5 dagen. Als je iets buiten dat bereik krijgt, is het zeker fout. Je kunt het juiste antwoord wiskundig bepalen voordat je de opgave maakt, maar dat kan behoorlijk lastig zijn.