Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND, Thierry Parmentelat

modalités

vous êtes censé travailler en local sur votre ordi; le zip contient

l’idée générale, c’est d’utiliser un workflow classique, qui consiste en ceci :

en effet, le fichier fourni de test test_rooks_and_queens.py sait valider votre code; c’est un exercice pour commencer à utiliser un framework de test
ici on va utiliser pytest, si nécessaire installez cet outil avec pip install pytest (eh oui :)

et avec ce setup

# vous pouvez faire `pytest` tout court aussi
$ pytest test_rooks_and_queens.py
================================ test session starts ================================
platform darwin -- Python 3.10.8, pytest-7.2.0, pluggy-1.0.0
rootdir: /Users/tparment/git/flotpython-exos/python-tps/queens
plugins: anyio-3.6.2
collected 3 items

test_rooks_and_queens.py ...                                                  [100%]

================================ 3 passed in 14.19s =================================

les tours

on se place sur un échiquier de taille n×nn \times n
on cherche à écrire un générateur qui énumère les positions de nn tours qui ne se menacent pas les unes les autres

système de coordonnées

les positions que l’on cherche ont toutes une bonne propriété, c’est que de par l’énoncé du problème on ne peut avoir qu’une position occupée sur chaque colonne de l’échiquier

aussi, pour se simplifier la vie

c’est ainsi qu’on va représenter une position, comme par exemple celle-ci

par le tuple (0, 4, 1, 2, 3) qui donne les coordonnées en Y dans les colonnes successives (ici le dessin est fait avec matplotlib, du coup les Y sont descendants, mais l’orientation n’a pas vraiment d’importance)

ce qu’on doit pouvoir faire

[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[1, 0, 2]
[0, 2, 1]
[2, 1, 0]

à quoi ça ressemble ?

il ne vous aura pas échappé que le problème est équivalent à énumérer les permutations de nn (et c’est d’ailleurs pour ça qu’on choisit de retourner une liste d’entiers, et non pas des tuples)

donc du coup on pourrait faire tout simplement

(0, 1, 2)
(0, 2, 1)
(1, 0, 2)
(1, 2, 0)
(2, 0, 1)
(2, 1, 0)

mais bon pour cet exercice on va vous demander de réfléchir à une façon de faire ça vous-même à la main, sans recourir à itertools donc...

les reines

forts de cet outil, on va maintenant vous demander d’énumérer les positions des reines qui ne se menacent pas les unes les autres

[2, 0, 3, 1, 4]
[0, 3, 1, 4, 2]
[3, 1, 4, 2, 0]
[1, 4, 2, 0, 3]
[4, 2, 0, 3, 1]
[1, 3, 0, 2, 4]
[3, 0, 2, 4, 1]
[0, 2, 4, 1, 3]
[2, 4, 1, 3, 0]
[4, 1, 3, 0, 2]
[3, 0, 4, 1, 5, 2]
[4, 2, 0, 5, 3, 1]
[1, 3, 5, 0, 2, 4]
[2, 5, 1, 4, 0, 3]

calculer la taille (longueur) d’un générateur

on ne peut pas utiliser len() sur un générateur (pourquoi ?)
comment feriez-vous pour calculer le nombre d’éléments dans un générateur ?

92

dessin

si vous avez fini avant tout le monde, dessinez les résultats avec numpy.imshow, (ou autre outil de visualisation de votre choix)

[2, 0, 3, 1]
<Figure size 640x480 with 1 Axes>
[1, 3, 0, 2]
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>

fin de la partie obligatoire

jusqu’ici c’est plutôt facile - ou court en tous cas; pour info ma correction tient en

la partie qui suit est intéressante aussi, et pas tellement plus longue en fait (13 lignes pour uniques dans mon cas), n’hésitez pas à vous y essayer aussi.

éliminez les symétries

(un tout petit peu) plus dur, éliminez les symétries et rotations

il y a plein de façons d’envisager la question, idéalement on doit pouvoir écrire un itérateur uniques qu’on pourra en quelque sorte chainer avec les deux algorithmes qu’on vient d’écrire

<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>
<Figure size 640x480 with 1 Axes>
23
421 ms ± 54 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)