UITWERKING Tentamen Programmeermethoden NA 8 december 2017 OPGAVE 1 a. def telparen(P): aantal_kar, aantal_getal = 0, 0 for el in P: if isgetal(el): aantal_getal += 1 elif iskar(el): aantal_kar += 1 if aantal_getal < aantal_kar: return aantal_getal else: return aantal_kar b. def zoekelement(P, getalkar): for i in reversed(range(len(P))): if getalkar and isgetal(P[i]): return i elif not getalkar and iskar(P[i]): return i return 0 c. def maakparen(P): for i in range(0, len(P), 2): if not isgetal(P[i]): j = zoekelement(P, True) P[i], P[j] = P[j], P[i] if not iskar(P[i+1]): j = zoekelement(P, False) P[i+1], P[j] = P[j], P[i+1] Een oplossing waarbij op even-posities (i % 2 == 0) een getal wordt geplaatst en op oneven een karakter is uiteraard ook goed. d. def wisselparen(P, i, j): P[i], P[j] = P[j], P[i] P[i+1], P[j+1] = P[j+1], P[i+1] e. def sorteerparen(P): for i in range(2, len(P), 2): for j in range(0, len(P) - i, 2): if P[j] > P[j+2]: wisselparen(P, j, j+2) f. def deelrij(L): langste, kleinste = 0, 0 lengte, klein = 0, -1 for el in L: if el >= 0: lengte += 1 if klein == -1 or el < klein: klein = el else: lengte = 0 klein = -1 if lengte > langste: langste = lengte kleinste = klein return langste, kleinste OPGAVE 2 a. Globale variabelen gelden in het gehele programma, en worden in de regel helemaal bovenin aangemaakt. Locale variabelen gelden (tijdelijk) alleen in de functie waarin ze aangemaakt zijn. Formeel: in functieheading, bijvoorbeeld x, y in def f(x, y): Actueel: bij aanroep, bijvoorbeeld 3 en z in print func (3,z) b. Bij het antwoord wordt een korte uitwerking/toelichting verwacht hoe het antwoord is verkregen. Q 2 3 1 Q 3 5 4 Q 2 3 1 Q 3 5 4 Q 4 7 9 Q 5 9 16 1 4 21 c. Uit een analyse van peppa volgt dat deze voor a en b groter dan 0 berekent a + b**2. Merk bij return t * (b - b + 1) op dat de term (b - b + 1) zal wegvallen. De returnwaarde is dus gelijk aan peppa(b, peppa(x, a + 2)). Dit kunnen we vereenvoudigen nadat we de nieuwe waarden voor b, x en a hebben geexpandeerd. peppa(b + 1, peppa(a - 1, a - 1 + 2) peppa(b + 1, peppa(a - 1, a + 1)) peppa(b + 1, a - 1 + (a + 1) ** 2) peppa(b + 1, a - 1 + (a ** 2 - 2 * a + 1)) peppa(b + 1, a - 1 + a ** 2 + 2 * a + 1) peppa(b + 1, a ** 2 + 3 * a) b + 1 + (a ** 2 + 3 * a) ** 2 Of verder uitgewerkt: b + 1 + a ** 4 + 6 * a ** 3 + 9 * a ** 2 In functievorm, bijvoorbeeld: def konijn(a, b): return b + 1 + (a ** 2 + 3 * a) ** 2 Of een eerdere tussenstap: def konijn(a, b): return b + 1 + (a - 1 + (a + 1) ** 2) ** 2 Of de geexpandeerde versie: def konijn(a, b): return b + 1 + a ** 4 + 6 * a ** 3 + 9 * a ** 2 d. De uitvoer verandert niet. Binnen peppa wordt nu de globale variabele som gebruikt die, net als de lokale variabele in de originele versie, telkens met 0 wordt geinitialiseerd. Ook wordt som in het oude en nieuwe geval overschreven door de return-waarde van george(), waardoor de uitvoer van het print-statement niet verandert. Ook bij meermaals uitvoeren verandert er niets. som wordt alleen binnen peppa() gebruikt (en hier telkens opnieuw geinitialiseerd) en heeft geen invloed op de waarden van de functie-argumenten. De functie-argumenten veranderen dus niet, waardoor functies altijd met dezelfde parameters worden aangeroepen. Omdat er ook geen side-effects van globale variabelen zijn blijft de uitvoer altijd hetzelfde. OPGAVE 3 a. M[4, :] b. M[::2, :] c. M[:, 3:5] d. M[::5, ::5] e. De kolom-as, dus axis=1. OPGAVE 4 Wij geven hier de uitwerkingen met behulp van loops. Antwoorden waarbij gebruik is gemaakt van NumPy functies en slices worden ook goed gerekend. a. def opgelost(F): getal = F[0,0] for i in range(n): for j in range(n): if F[i,j] != getal: return False return True b. def buurinmask(mask, i, j): if i > 0 and mask[i-1, j]: return True elif j > 0 and mask[i, j-1]: return True elif i < n - 1 and mask[i+1, j]: return True elif j < n - 1 and mask[i, j+1]: return True return False c. def gebied(F): mask = np.zeros(F.shape, dtype=np.bool) mask[0, 0] = True aangepast = True while aangepast: aangepast = False for i in range(n): for j in range(n): if not mask[i,j] and buurinmask(mask, i, j) and \ F[i,j] == F[0,0]: mask[i, j] = True aangepast = True return mask d. def kiesgetal(F, mask): hulp = np.zeros(k) for i in range(n): for j in range(n): if not mask[i, j] and buurinmask(mask, i, j): hulp[F[i,j]-1] += 1 grootste = 0 for i in range(1, k): if hulp[i] > hulp[grootste]: grootste = i return grootste + 1 e. def oplossen(F): stappen = 0 while not opgelost(F): mask = gebied(F) getal = kiesgetal(F, mask) F[mask] = getal stappen += 1 return stappen