Skip to content

Commit 37baa58

Browse files
committed
slight review of queens
1 parent 8b9430c commit 37baa58

File tree

5 files changed

+106
-46
lines changed

5 files changed

+106
-46
lines changed

notebooks/tps/queens/.teacher/README-queens-corrige-nb.md

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
---
22
jupytext:
3-
cell_metadata_filter: all,-hidden,-heading_collapsed,-run_control,-trusted
43
encoding: '# -*- coding: utf-8 -*-'
5-
notebook_metadata_filter: all, -jupytext.text_representation.jupytext_version, -jupytext.text_representation.format_version,
6-
-language_info.version, -language_info.codemirror_mode.version, -language_info.codemirror_mode,
7-
-language_info.file_extension, -language_info.mimetype, -toc
84
text_representation:
95
extension: .md
106
format_name: myst
@@ -70,24 +66,31 @@ test_rooks_and_queens.py ... [1
7066
================================ 3 passed in 14.19s =================================
7167
```
7268

73-
mais bien sûr d'ici là, n'hésitez pas à lancer votre code interactivement et le debugger, soit dans ce notebook, soit dans ipython, etc..
69+
```{admonition} il faut débugger avant de tester !
70+
:class: important
71+
72+
MAIS BIEN SÛR avant de lancer les tests, il est ***impératif** d'avoir d'abord lancé votre code interactivement, et de l'avoir débuggé - que soit dans le notebook ou dans ipython
73+
```
7474

7575
+++
7676

77+
````{admonition} l'autoreload
78+
:class: danger
79+
7780
il y a toutefois une précaution à prendre si vous travaillez comme ceci
78-
en effet l'import d'un module est **caché** par Python, ce qui fait que par défaut, les changements que vous faites dans fichier `rooks_and_queens.py` ne sont plus rechargés après le premier import
81+
en effet l'import d'un module est **caché** par Python, ce qui fait que par défaut, les changements que vous faites dans fichier `rooks_and_queens.py` ne sont **plus rechargés après le premier import**
7982
8083
pour vous installer confortablement, voyez ce lien:
81-
<https://flotpython-exos-python.readthedocs.io/en/main/README.html#note-on-autoreload-in-ipython-or-notebooks>
84+
https://ue12-p24-intro.readthedocs.io/en/main/1-01-installations-nb.html#configuration-de-l-autoreload
85+
````
8286

8387
+++
8488

8589
## les tours
8690

8791
+++
8892

89-
on se place sur un échiquier de taille $n \times n$
90-
93+
on se place sur un échiquier de taille $n \times n$
9194
on cherche à écrire un générateur qui énumère **les positions de $n$ tours** qui ne se menacent pas les unes les autres
9295

9396
+++
@@ -106,7 +109,7 @@ c'est ainsi qu'on va représenter une position, comme par exemple celle-ci
106109
:align: center
107110
```
108111

109-
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, l'orientation n'a pas d'importance)
112+
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)
110113

111114
```{code-cell} ipython3
112115
# prune-cell
@@ -142,16 +145,16 @@ next(r3)
142145
```
143146

144147
```{code-cell} ipython3
145-
# on a déjà consommé 3 des 6 positions :
146-
# si on fait une boucle for on ne voit plus que les 3 dernières
148+
# on a déjà consommé 3 des 6 positions; du coup ...
149+
# si maintenant on fait une boucle for on ne voit plus que les 3 dernières !
147150
148151
for position in r3:
149152
print(position)
150153
```
151154

152155
### à quoi ça ressemble ?
153156

154-
il ne vous aura pas échappé que le problème est équivalent à énumérer les permutations de $n$ (et c'est d'ailleurs pour ça qu'on peut se permettre de retourner une liste d'entiers, et non pas des tuples)
157+
il ne vous aura pas échappé que le problème est équivalent à énumérer les permutations de $n$ (et c'est d'ailleurs pour ça qu'on choisit de retourner une liste d'entiers, et non pas des tuples)
155158

156159
donc du coup on pourrait faire tout simplement
157160

@@ -202,21 +205,16 @@ for p in queens(6):
202205
# ...
203206
```
204207

205-
+++ {"tags": ["level_intermediate"]}
206-
207-
## pour les rapides
208-
209-
cette partie est optionnelle
210-
211-
+++
212-
213208
### calculer la taille (longueur) d'un générateur
214209

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

218213
```{code-cell} ipython3
219214
# écrivez generator_size
215+
# ATTENTION quand même à NE PAS créer une liste dans ce code
216+
# car comme résultat on veut un entier hein
217+
# pas besoin de consommer toute la mémoire de l'ordi pour ça hein !
220218
221219
from rooks_and_queens import generator_size
222220
generator_size(queens(8))
@@ -226,7 +224,7 @@ generator_size(queens(8))
226224

227225
+++
228226

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

231229
```{code-cell} ipython3
232230
%matplotlib inline
@@ -241,13 +239,32 @@ for p in queens(4):
241239
```
242240

243241
```{code-cell} ipython3
242+
:scrolled: true
243+
244244
for p in queens(6):
245245
draw_position(p)
246246
```
247247

248+
+++ {"tags": []}
249+
250+
## fin de la partie obligatoire
251+
252+
jusqu'ici c'est plutôt facile - ou court en tous cas; pour info ma correction tient en
253+
254+
- 7 lignes pour `rooks`
255+
- 7 lignes pour `queens`
256+
- 2 lignes pour `generator_size`
257+
- `draw_position` est - de manière contrintuitive - bien plus long
258+
il faut dire que je suis passé par deux fonctions pour traduire entre les tuples d'entiers et le tableau numpy;
259+
en fait une seule aurait suffi, mais pour la suite j'ai tiré profit des deux
260+
261+
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.
262+
263+
+++
264+
248265
### éliminez les symétries
249266

250-
plus dur, éliminez les symétries et rotations
267+
(un tout petit peu) plus dur, éliminez les symétries et rotations
251268

252269
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
253270

@@ -257,15 +274,16 @@ from rooks_and_queens import uniques
257274
```
258275

259276
```{code-cell} ipython3
260-
# comme vous pouvez le voir plus haut, les solutions de queens(6)
261-
# sont toutes les mêmes mais tournées à chaque fois d'1/4 de tour
277+
# en fait les 4 solutions de queens(6) sont toutes les mêmes
262278
# aussi quand on passe par uniques() il n'en reste qu'une
279+
263280
for p in uniques(queens(6)):
264281
draw_position(p)
265282
```
266283

267284
```{code-cell} ipython3
268285
# en dimension 5 curieusement il y en a plus que pour n=6
286+
269287
for p in uniques(queens(5)):
270288
draw_position(p)
271289
```
@@ -277,3 +295,11 @@ for p in uniques(queens(5)):
277295
278296
generator_size(uniques(rooks(5)))
279297
```
298+
299+
```{code-cell} ipython3
300+
# et dans le cas de l'échiquier "normal"
301+
# voici à peu près la performance que vous pouvez obtenir
302+
# sans trop chercher à optimiser...
303+
304+
%timeit generator_size(uniques(rooks(8)))
305+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../rooks_and_queens.py
498 Bytes
Binary file not shown.

notebooks/tps/queens/README-queens-nb.md

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,31 @@ test_rooks_and_queens.py ... [1
6666
================================ 3 passed in 14.19s =================================
6767
```
6868

69-
mais bien sûr d'ici là, n'hésitez pas à lancer votre code interactivement et le debugger, soit dans ce notebook, soit dans ipython, etc..
69+
```{admonition} il faut débugger avant de tester !
70+
:class: important
71+
72+
MAIS BIEN SÛR avant de lancer les tests, il est ***impératif** d'avoir d'abord lancé votre code interactivement, et de l'avoir débuggé - que soit dans le notebook ou dans ipython
73+
```
7074

7175
+++
7276

77+
````{admonition} l'autoreload
78+
:class: danger
79+
7380
il y a toutefois une précaution à prendre si vous travaillez comme ceci
74-
en effet l'import d'un module est **caché** par Python, ce qui fait que par défaut, les changements que vous faites dans fichier `rooks_and_queens.py` ne sont plus rechargés après le premier import
81+
en effet l'import d'un module est **caché** par Python, ce qui fait que par défaut, les changements que vous faites dans fichier `rooks_and_queens.py` ne sont **plus rechargés après le premier import**
7582
7683
pour vous installer confortablement, voyez ce lien:
77-
<https://flotpython-exos-python.readthedocs.io/en/main/README.html#note-on-autoreload-in-ipython-or-notebooks>
84+
https://ue12-p24-intro.readthedocs.io/en/main/1-01-installations-nb.html#configuration-de-l-autoreload
85+
````
7886

7987
+++
8088

8189
## les tours
8290

8391
+++
8492

85-
on se place sur un échiquier de taille $n \times n$
86-
93+
on se place sur un échiquier de taille $n \times n$
8794
on cherche à écrire un générateur qui énumère **les positions de $n$ tours** qui ne se menacent pas les unes les autres
8895

8996
+++
@@ -102,7 +109,7 @@ c'est ainsi qu'on va représenter une position, comme par exemple celle-ci
102109
:align: center
103110
```
104111

105-
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, l'orientation n'a pas d'importance)
112+
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)
106113

107114
+++
108115

@@ -133,16 +140,16 @@ next(r3)
133140
```
134141

135142
```{code-cell} ipython3
136-
# on a déjà consommé 3 des 6 positions :
137-
# si on fait une boucle for on ne voit plus que les 3 dernières
143+
# on a déjà consommé 3 des 6 positions; du coup ...
144+
# si maintenant on fait une boucle for on ne voit plus que les 3 dernières !
138145
139146
for position in r3:
140147
print(position)
141148
```
142149

143150
### à quoi ça ressemble ?
144151

145-
il ne vous aura pas échappé que le problème est équivalent à énumérer les permutations de $n$ (et c'est d'ailleurs pour ça qu'on peut se permettre de retourner une liste d'entiers, et non pas des tuples)
152+
il ne vous aura pas échappé que le problème est équivalent à énumérer les permutations de $n$ (et c'est d'ailleurs pour ça qu'on choisit de retourner une liste d'entiers, et non pas des tuples)
146153

147154
donc du coup on pourrait faire tout simplement
148155

@@ -193,21 +200,16 @@ for p in queens(6):
193200
# ...
194201
```
195202

196-
+++ {"tags": ["level_intermediate"]}
197-
198-
## pour les rapides
199-
200-
cette partie est optionnelle
201-
202-
+++
203-
204203
### calculer la taille (longueur) d'un générateur
205204

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

209208
```{code-cell} ipython3
210209
# écrivez generator_size
210+
# ATTENTION quand même à NE PAS créer une liste dans ce code
211+
# car comme résultat on veut un entier hein
212+
# pas besoin de consommer toute la mémoire de l'ordi pour ça hein !
211213
212214
from rooks_and_queens import generator_size
213215
generator_size(queens(8))
@@ -217,7 +219,7 @@ generator_size(queens(8))
217219

218220
+++
219221

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

222224
```{code-cell} ipython3
223225
%matplotlib inline
@@ -232,13 +234,32 @@ for p in queens(4):
232234
```
233235

234236
```{code-cell} ipython3
237+
:scrolled: true
238+
235239
for p in queens(6):
236240
draw_position(p)
237241
```
238242

243+
+++ {"tags": []}
244+
245+
## fin de la partie obligatoire
246+
247+
jusqu'ici c'est plutôt facile - ou court en tous cas; pour info ma correction tient en
248+
249+
- 7 lignes pour `rooks`
250+
- 7 lignes pour `queens`
251+
- 2 lignes pour `generator_size`
252+
- `draw_position` est - de manière contrintuitive - bien plus long
253+
il faut dire que je suis passé par deux fonctions pour traduire entre les tuples d'entiers et le tableau numpy;
254+
en fait une seule aurait suffi, mais pour la suite j'ai tiré profit des deux
255+
256+
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.
257+
258+
+++
259+
239260
### éliminez les symétries
240261

241-
plus dur, éliminez les symétries et rotations
262+
(un tout petit peu) plus dur, éliminez les symétries et rotations
242263

243264
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
244265

@@ -248,15 +269,16 @@ from rooks_and_queens import uniques
248269
```
249270

250271
```{code-cell} ipython3
251-
# comme vous pouvez le voir plus haut, les solutions de queens(6)
252-
# sont toutes les mêmes mais tournées à chaque fois d'1/4 de tour
272+
# en fait les 4 solutions de queens(6) sont toutes les mêmes
253273
# aussi quand on passe par uniques() il n'en reste qu'une
274+
254275
for p in uniques(queens(6)):
255276
draw_position(p)
256277
```
257278

258279
```{code-cell} ipython3
259280
# en dimension 5 curieusement il y en a plus que pour n=6
281+
260282
for p in uniques(queens(5)):
261283
draw_position(p)
262284
```
@@ -268,3 +290,11 @@ for p in uniques(queens(5)):
268290
269291
generator_size(uniques(rooks(5)))
270292
```
293+
294+
```{code-cell} ipython3
295+
# et dans le cas de l'échiquier "normal"
296+
# voici à peu près la performance que vous pouvez obtenir
297+
# sans trop chercher à optimiser...
298+
299+
%timeit generator_size(uniques(rooks(8)))
300+
```

notebooks/tps/queens/rooks_and_queens.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ def generator_size(gen):
9292
return sum(1 for _ in gen)
9393

9494

95+
# in this part we call
96+
# - position a tuple of ints
97+
# - np a numpy array
9598

9699
import numpy as np
97100

0 commit comments

Comments
 (0)