Skip to content

Commit 40802cc

Browse files
authored
Add notebook for 9/4 (#71)
* Add notebook for 9/4 * normalize
1 parent 22c05c3 commit 40802cc

4 files changed

Lines changed: 272 additions & 1 deletion

File tree

_doc/articles/2024/2024-11-31-route2024.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,60 @@
11
2024-11-31 : rappel feuille de route 2024
22
=========================================
33

4+
Le plan des séances est changé après que celles-ci ont eu lieu.
5+
46
Séance 1
57
++++++++
68

9+
:ref:`Prises aux dames <nbl-practice-py-base-dame_prise>`
10+
711
Séance 2
812
++++++++
913

14+
Tests unitaires et classes
15+
1016
Séance 3
1117
++++++++
1218

19+
:ref:`classes pour représenter un graphe <nbl-practice-py-base-classe_tree>`
20+
21+
Fin des classes puis :ref:`les itérateurs <nbl-practice-py-base-classe_iterateur>` et
22+
:ref:`numpy broadcast <nbl-c_data-numpy_broadcast>`.
23+
1324
Séance 4
1425
++++++++
1526

27+
Dame et minimax.
28+
1629
Séance 5
1730
++++++++
1831

32+
* :ref:`Distance d'édition <nbl-practice-years-2023-editdist>`
33+
* :ref:`Pivot de Gauss <nbl-practice-years-2023-pivot_gauss>`
34+
35+
A propos de la distance d'édition, voir aussi
36+
:ref:`Distance d'édition <nbl-practice-algo-base-exercice_edit_distance>` ou encore
37+
:ref:`Distance entre deux mots de même longueur et tests unitaires <nbl-practice-algo-base-exercice_editdist>`.
38+
1939
Séance 6
2040
++++++++
2141

42+
* :ref:`Le voyageur de commerce <nbl-practice-algo-base-tsp_simplifie>`
43+
* :ref:`Recheche à base de préfixes <nbl-practice-years-2023-prefix_search>`
44+
45+
Autres variations autour du problème du voyageur de commerce,
46+
ou TSP pour Travelling Salesman Problem
47+
ou encore circuit hamiltonien: :ref:`l-tsp_kohonen`, :ref:`l-tsp_kruskal`.
48+
2249
Séance 7
2350
++++++++
2451

52+
* :ref:`Classe et héritage <nbl-practice-py-base-classe_user_p>`
53+
2554
Séance 8
2655
++++++++
2756

57+
* :ref:`Optimisation de la note moyenne <nbl-practice-years-2023-bareme_note_optimisation>`
2858

2959
TD noté 1h30 en seconde partie.
3060
Classes et un algorithme.

_doc/practice/index_python.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Exercices sur le langage python
3939
py-base/histogramme_rapide
4040
py-base/exercice_pi
4141
py-base/de_rotation
42+
py-base/dame_prise
4243
../auto_examples/prog/plot_matador
4344
../auto_examples/prog/plot_partie_dame
4445

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Exercices autour des dames\n",
8+
"\n",
9+
"Comment écrire une fonction qui retourne tous les pions qu'une dame peut prendre au [jeu de dames](https://fr.wikipedia.org/wiki/Dames).\n",
10+
"\n",
11+
"Après avoir créé un damier, on créé deux fonctions :\n",
12+
"\n",
13+
"* une fonction qui retourne les dames et les pions\n",
14+
"* une fonction qui retourne les pions qu'une dame peut prendre\n",
15+
"\n",
16+
"Il suffira d'appeler la fonction pour toutes les dames du jeu pour connaître tous les pions qu'un joueur peut prendre avec ses dames.\n",
17+
"\n",
18+
"Dans un premier temps, il convient de représenter le damier. On choisira une matrice [numpy](https://numpy.org/) qu'il faut remplir de valeur numérique :\n",
19+
"\n",
20+
"* 0: case vide\n",
21+
"* 1: pion blanc\n",
22+
"* 2: pion noir\n",
23+
"* 3: dame blanche\n",
24+
"* 4: dame noir\n",
25+
"\n",
26+
"Les valeurs numériques sont toujours plus efficace que des chaînes de caractères. Elles prennent moins de place en mémoire et les opérations sont plus efficaces."
27+
]
28+
},
29+
{
30+
"cell_type": "code",
31+
"execution_count": 5,
32+
"metadata": {},
33+
"outputs": [
34+
{
35+
"name": "stdout",
36+
"output_type": "stream",
37+
"text": [
38+
"[[3 0 0 0 0 0 0 0 0 0]\n",
39+
" [0 0 0 0 0 0 0 0 0 0]\n",
40+
" [0 0 0 0 0 0 0 0 0 0]\n",
41+
" [0 0 0 0 0 0 0 0 0 0]\n",
42+
" [0 0 0 0 2 0 2 0 0 0]\n",
43+
" [0 0 0 0 0 0 0 0 0 0]\n",
44+
" [0 0 0 0 0 0 0 0 0 0]\n",
45+
" [0 0 0 0 0 0 0 0 0 0]\n",
46+
" [0 0 0 0 0 0 0 0 0 0]\n",
47+
" [0 0 0 0 0 0 0 0 0 0]]\n"
48+
]
49+
}
50+
],
51+
"source": [
52+
"import numpy as np\n",
53+
"\n",
54+
"\n",
55+
"def damier_exemple(n: int = 10):\n",
56+
" d = np.zeros(\n",
57+
" (n, n), dtype=int # il est préférable d'avoir des entiers plutôt que des réels\n",
58+
" )\n",
59+
" d[0, 0] = 3\n",
60+
" d[4, 4] = 2\n",
61+
" d[4, 6] = 2\n",
62+
" return d\n",
63+
"\n",
64+
"\n",
65+
"damier = damier_exemple()\n",
66+
"print(damier)"
67+
]
68+
},
69+
{
70+
"cell_type": "markdown",
71+
"metadata": {},
72+
"source": [
73+
"On cherche maintenant toutes les dames. On retourne une liste de position. Il n'est pas utile de retourner ce que contient chaque case. On peut retrouver cette information avec le damier."
74+
]
75+
},
76+
{
77+
"cell_type": "code",
78+
"execution_count": 6,
79+
"metadata": {},
80+
"outputs": [
81+
{
82+
"data": {
83+
"text/plain": [
84+
"[(0, 0), (4, 4), (4, 6)]"
85+
]
86+
},
87+
"execution_count": 6,
88+
"metadata": {},
89+
"output_type": "execute_result"
90+
}
91+
],
92+
"source": [
93+
"def cherche_dames(damier) -> list[tuple[int, int]]:\n",
94+
" res = []\n",
95+
" for i in range(damier.shape[0]):\n",
96+
" for j in range(damier.shape[1]):\n",
97+
" if damier[i, j] > 0:\n",
98+
" res.append((i, j))\n",
99+
" return res\n",
100+
"\n",
101+
"\n",
102+
"res = cherche_dames(damier)\n",
103+
"res"
104+
]
105+
},
106+
{
107+
"cell_type": "markdown",
108+
"metadata": {},
109+
"source": [
110+
"Et maintenant, le plat principal, une fonction retourne les possibles prises pour une dame. L'idée est de regarder dans une direction, de chercher un pion ou une dame de couleur différente et une autre case derrière, et plus précisément, la dernière case où la dame peut se poser. La fonction retourne deux positions : ``[(i1, j1), (i2, j2)]``. La première position est le pion ou la dame à prendre. La dame peut alors se poser dans l'intervalle entre ces deux positions, la première exlue.\n",
111+
"\n",
112+
"Comme cet algorithme est le même quelle que soit la direction, nous allons créer deux fonctions, une pour traiter une direction, l'autre pour les quatre."
113+
]
114+
},
115+
{
116+
"cell_type": "code",
117+
"execution_count": 13,
118+
"metadata": {},
119+
"outputs": [
120+
{
121+
"name": "stdout",
122+
"output_type": "stream",
123+
"text": [
124+
"prise=(4, 4), pose=(9, 9)\n"
125+
]
126+
}
127+
],
128+
"source": [
129+
"def position_prise_direction(\n",
130+
" damier, position_dame: tuple[int, int], direction: tuple[int, int]\n",
131+
") -> list[tuple[int, int]]:\n",
132+
" assert damier[position_dame] >= 3, f\"ce n'est pas une dame {damier[position_dame]}\"\n",
133+
" couleur = damier[position_dame] % 2\n",
134+
" prise = None\n",
135+
" pose = None\n",
136+
" i, j = position_dame\n",
137+
" di, dj = direction\n",
138+
" i += di\n",
139+
" j += dj\n",
140+
" while i >= 0 and i < damier.shape[0] and j >= 0 and j < damier.shape[1]:\n",
141+
" case = damier[i, j]\n",
142+
" if prise is None:\n",
143+
" if case == 0:\n",
144+
" i += di\n",
145+
" j += dj\n",
146+
" continue\n",
147+
" if case % 2 == couleur: # même couleur\n",
148+
" return None, None\n",
149+
" # sinon on prend\n",
150+
" prise = i, j\n",
151+
" i += di\n",
152+
" j += dj\n",
153+
" continue\n",
154+
" # si la prise a déjà eu lieu\n",
155+
" if case == 0:\n",
156+
" # on peut poser la dame\n",
157+
" pose = i, j\n",
158+
" i += di\n",
159+
" j += dj\n",
160+
" continue\n",
161+
"\n",
162+
" # sinon\n",
163+
" if prise is None:\n",
164+
" # pas de case libre derrière donc on ne peut pas prendre\n",
165+
" return None, None\n",
166+
"\n",
167+
" return prise, pose\n",
168+
"\n",
169+
" # La boucle est terminée sans passer par une instruction return?\n",
170+
" return prise, pose\n",
171+
"\n",
172+
"\n",
173+
"prise, pose = position_prise_direction(damier, (0, 0), (1, 1))\n",
174+
"print(f\"prise={prise}, pose={pose}\")"
175+
]
176+
},
177+
{
178+
"cell_type": "markdown",
179+
"metadata": {},
180+
"source": [
181+
"Et la fonction suivante pour traiter les quatre directions :"
182+
]
183+
},
184+
{
185+
"cell_type": "code",
186+
"execution_count": 16,
187+
"metadata": {},
188+
"outputs": [
189+
{
190+
"name": "stdout",
191+
"output_type": "stream",
192+
"text": [
193+
"[((4, 4), (9, 9))]\n"
194+
]
195+
}
196+
],
197+
"source": [
198+
"def position_prise(damier, position_dame: tuple[int, int]) -> list[tuple[int, int]]:\n",
199+
" res = []\n",
200+
" for di in [-1, 1]:\n",
201+
" for dj in [-1, 1]:\n",
202+
" prise, pose = position_prise_direction(damier, position_dame, (di, dj))\n",
203+
" if prise is None:\n",
204+
" continue\n",
205+
" res.append((prise, pose))\n",
206+
" return res\n",
207+
"\n",
208+
"\n",
209+
"res = position_prise(damier, (0, 0))\n",
210+
"print(res)"
211+
]
212+
},
213+
{
214+
"cell_type": "markdown",
215+
"metadata": {},
216+
"source": []
217+
}
218+
],
219+
"metadata": {
220+
"kernelspec": {
221+
"display_name": "Python 3 (ipykernel)",
222+
"language": "python",
223+
"name": "python3"
224+
},
225+
"language_info": {
226+
"codemirror_mode": {
227+
"name": "ipython",
228+
"version": 3
229+
},
230+
"file_extension": ".py",
231+
"mimetype": "text/x-python",
232+
"name": "python",
233+
"nbconvert_exporter": "python",
234+
"pygments_lexer": "ipython3",
235+
"version": "3.10.12"
236+
}
237+
},
238+
"nbformat": 4,
239+
"nbformat_minor": 1
240+
}

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
black
2-
black-nb
32
blockdiag
43
cartopy
54
catboost
@@ -16,6 +15,7 @@ geopandas
1615
ipython
1716
jinja2
1817
jupyter
18+
jupyter-black
1919
lifelines
2020
lightgbm
2121
lxml

0 commit comments

Comments
 (0)