Boter, kaas en eieren¶
De acht functies controleren of er drie of n keer hetzelfde karakter op een rij staat, vanaf een startpositie en in een gegeven richting, in een 2D-lijst array.
De cel hieronder is de gegeven code uit het practicum, woordelijk overgenomen. Hier draait ze wél, zodat we zeker weten dat wat de student overneemt ook werkt.
# een functie om een 2D-lijst af te drukken
def print_2d(array):
"""Drukt de 2D-lijst array af, met een regel per rij.
Argument: array, een 2D-lijst
Resultaat: None (geen returnwaarde)
"""
n_rows = len(array)
n_cols = len(array[0])
for row_ix in range(n_rows): # n_rows == aantal rijen
for col_ix in range(n_cols): # n_cols == aantal kolommen
print(array[row_ix][col_ix], end=" ")
print()
return None # dit is impliciet aanwezig
# als er geen return-statement aanwezig is
# een paar tests voor print_2d
array = [["X", " ", "O"], ["O", "X", "O"]]
print("2-row, 3-col array is")
print_2d(array)
array = [["X", "O"], [" ", "X"], ["O", "O"], ["O", "X"]]
print("4-row, 2-col array is")
print_2d(array)
# maak een 2D-lijst van een eendimensionale string
def create_array(n_rows, n_cols, s):
"""Geeft een 2D-lijst terug met n_rows rijen en n_cols kolommen.
De gegevens komen uit de string s: eerst de eerste rij vol,
dan de tweede, enzovoort. We testen alleen met genoeg gegevens!
"""
array = []
for _ in range(n_rows):
new_row = []
for _ in range(n_cols):
new_row += [s[0]] # voeg dat karakter toe
s = s[1:] # verwijder het eerste karakter
array += [new_row]
return array
# een paar tests voor create_array:
array = [["X", " ", "O"], ["O", "X", "O"]]
new_array = create_array(2, 3, "X OOXO")
assert new_array == array
print("Is new_array == array? moet True zijn:", new_array == array)
array = [["X", "O"], [" ", "X"], ["O", "O"], ["O", "X"]]
new_array = create_array(4, 2, "XO XOOOX")
assert new_array == array
2-row, 3-col array is
X O
O X O
4-row, 2-col array is
X O
X
O O
O X
Is new_array == array? moet True zijn: True
Drie op een rij¶
Alle vier de functies hebben dezelfde vorm: eerst de grenscontroles, dan een lus over drie posities.
Opdracht 1¶
def in_a_row_3_east(char, row_start, col_start, array):
"""Geeft True terug als er vanaf (row_start, col_start) drie keer char naar het oosten staat."""
n_rows = len(array) # aantal rijen is len(array)
n_cols = len(array[0]) # aantal kolommen is len(array[0])
if row_start >= n_rows:
return False # buiten de grenzen van de rijen
# andere grenscontroles...
if col_start > n_cols - 3:
return False # buiten de grenzen van de kolommen
# zijn alle gegevenselementen correct?
for ix in range(3): # lusindex is ix
if array[row_start][col_start + ix] != char: # controleer op fouten
return False # fout gevonden; geef False terug
return True # geen fouten gevonden in de lus; geef True terug
# tests voor in_a_row_3_east
array = create_array(3, 4, "XXOXXXOOOOOO")
assert not in_a_row_3_east("X", 0, 0, array)
assert in_a_row_3_east("O", 2, 1, array)
assert not in_a_row_3_east("X", 2, 1, array)
assert not in_a_row_3_east("O", 2, 2, array)
Opdracht 2¶
def in_a_row_3_south(char, row_start, col_start, array):
"""Geeft True terug als er vanaf (row_start, col_start) drie keer char naar het zuiden staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start >= n_cols:
return False # buiten de grenzen van de kolommen
if row_start > n_rows - 3:
return False # buiten de grenzen van de rijen
for ix in range(3):
if array[row_start + ix][col_start] != char:
return False
return True
# tests voor in_a_row_3_south
array = create_array(4, 4, "XXOXXXOXXOO OOOX")
assert in_a_row_3_south("X", 0, 0, array)
assert not in_a_row_3_south("O", 2, 2, array)
assert not in_a_row_3_south("X", 1, 3, array)
assert not in_a_row_3_south("O", 42, 42, array)
Opdracht 3¶
def in_a_row_3_southeast(char, row_start, col_start, array):
"""Geeft True terug als er vanaf (row_start, col_start) drie keer char naar het zuidoosten staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start > n_cols - 3:
return False
if row_start > n_rows - 3:
return False
for ix in range(3):
if array[row_start + ix][col_start + ix] != char:
return False
return True
# tests voor in_a_row_3_southeast
array = create_array(4, 4, "XOOXXXOXX XOOOOX")
assert in_a_row_3_southeast("X", 1, 1, array)
assert not in_a_row_3_southeast("X", 1, 0, array)
assert in_a_row_3_southeast("O", 0, 1, array)
assert not in_a_row_3_southeast("X", 2, 2, array)
Opdracht 4¶
def in_a_row_3_northeast(char, row_start, col_start, array):
"""Geeft True terug als er vanaf (row_start, col_start) drie keer char naar het noordoosten staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start > n_cols - 3:
return False
if row_start < 3 - 1: # naar het noorden is er te weinig ruimte
return False
if row_start >= n_rows:
return False
for ix in range(3):
if array[row_start - ix][col_start + ix] != char:
return False
return True
# tests voor in_a_row_3_northeast
array = create_array(4, 4, "XOXXXXOXXOXOOOOX")
assert in_a_row_3_northeast("X", 2, 0, array)
assert in_a_row_3_northeast("O", 3, 0, array)
assert not in_a_row_3_northeast("O", 3, 1, array)
assert not in_a_row_3_northeast("X", 3, 3, array)
Van 3 naar N: N op een rij¶
Het generaliseren zit op drie plekken: de grenscontrole rekent met n in plaats van met 3, de lus loopt n keer, en de richting blijft precies zoals ze was.
Opdracht 5¶
def in_a_row_n_east(char, row_start, col_start, array, n):
"""Geeft True terug als er vanaf (row_start, col_start) n keer char naar het oosten staat."""
n_rows = len(array)
n_cols = len(array[0])
if row_start >= n_rows:
return False
if col_start > n_cols - n:
return False
for ix in range(n):
if array[row_start][col_start + ix] != char:
return False
return True
# tests voor in_a_row_n_east
array = create_array(5, 5, "XXOXXXOOOOOOXXXX XXXOOOOO")
assert in_a_row_n_east("O", 1, 1, array, 4)
assert in_a_row_n_east("O", 1, 3, array, 2)
assert not in_a_row_n_east("X", 3, 2, array, 4)
assert in_a_row_n_east("O", 4, 0, array, 5)
Opdracht 6¶
def in_a_row_n_south(char, row_start, col_start, array, n):
"""Geeft True terug als er vanaf (row_start, col_start) n keer char naar het zuiden staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start >= n_cols:
return False
if row_start > n_rows - n:
return False
for ix in range(n):
if array[row_start + ix][col_start] != char:
return False
return True
# tests voor in_a_row_n_south
array = create_array(5, 5, "XXOXXXOOOOOOXXXXOXXXOOOXO")
assert not in_a_row_n_south("X", 0, 0, array, 5)
assert in_a_row_n_south("O", 1, 1, array, 4)
assert not in_a_row_n_south("O", 0, 1, array, 6)
assert in_a_row_n_south("X", 4, 3, array, 1)
Opdracht 7¶
def in_a_row_n_southeast(char, row_start, col_start, array, n):
"""Geeft True terug als er vanaf (row_start, col_start) n keer char naar het zuidoosten staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start > n_cols - n:
return False
if row_start > n_rows - n:
return False
for ix in range(n):
if array[row_start + ix][col_start + ix] != char:
return False
return True
# tests voor in_a_row_n_southeast
array = create_array(5, 5, "XOO XXXOXOOOXXXXOXXXOOOXX")
assert in_a_row_n_southeast("X", 1, 1, array, 4)
assert not in_a_row_n_southeast("O", 0, 1, array, 3)
assert in_a_row_n_southeast("O", 0, 1, array, 2)
assert not in_a_row_n_southeast("X", 3, 0, array, 2)
Opdracht 8¶
def in_a_row_n_northeast(char, row_start, col_start, array, n):
"""Geeft True terug als er vanaf (row_start, col_start) n keer char naar het noordoosten staat."""
n_rows = len(array)
n_cols = len(array[0])
if col_start > n_cols - n:
return False
if row_start < n - 1: # naar het noorden is er te weinig ruimte
return False
if row_start >= n_rows:
return False
for ix in range(n):
if array[row_start - ix][col_start + ix] != char:
return False
return True
# tests voor in_a_row_n_northeast
array = create_array(5, 5, "XOO XXXOXOOOXOXXXOXXXOOXX")
assert in_a_row_n_northeast("X", 4, 0, array, 5)
assert in_a_row_n_northeast("O", 4, 1, array, 4)
assert not in_a_row_n_northeast("O", 2, 0, array, 2)
assert not in_a_row_n_northeast("X", 0, 3, array, 1)
Randgevallen¶
# een randgeval per functie: een positie net buiten de grenzen
array = create_array(3, 3, "XXXXXXXXX")
assert not in_a_row_3_east("X", 0, 1, array)
assert not in_a_row_3_south("X", 1, 0, array)
assert not in_a_row_3_southeast("X", 1, 1, array)
assert not in_a_row_3_northeast("X", 1, 0, array)
assert not in_a_row_n_east("X", 0, 1, array, 3)
assert not in_a_row_n_south("X", 1, 0, array, 3)
assert not in_a_row_n_southeast("X", 1, 1, array, 3)
assert not in_a_row_n_northeast("X", 1, 0, array, 3)
# n gelijk aan 1 vindt altijd het element op de startpositie zelf
assert in_a_row_n_east("X", 2, 2, array, 1)
assert in_a_row_n_northeast("X", 0, 0, array, 1)