Tout d'abord, la position de la lettre dans la grille est facile à calculer :
function get_pos( c : char)
begin
int col ← (c-'A') modulo 4
int row ← (c-'A') div 4
return (row,col)
end
En supposant que les positions (6,2) et (6,3) peuvent être utilisées
Nous pouvons simplement définir une soustraction entre les coordonnées des cellules comme :
function subtract( pos1, pos2 : position )
begin
return (pos2.row-pos1.row, pos2.col-pos1.col)
end
Si la soustraction donne une paire (x,y), le chemin est simplement x fois le caractère 'R' si x est positif ou 'L' si x est négatif, éventuellement rien si x est zéro, et de même y fois le caractère 'D' si y est positif ou 'U' si y est négatif, éventuellement rien si y est zéro, puis nous terminons avec le caractère 'E'.
function print_row_path( pos1, pos2 : position )
begin
path ← subtract(pos1,pos2)
if path.row > 0 then
print_times_char(path.row,'R')
else if path.row < 0
print_times_char(-path.row,'L')
end if
end
function print_col_path( pos1, pos2 : position )
begin
path ← subtract(pos1,pos2)
if path.col > 0 then
print_times_char(path.col,'D')
else if path.col < 0
print_times_char(-path.col,'U')
end if
end
function print_path_direction( pos1, pos2 : position ; first_direction : direction )
begin
if (first_direction = FIRST_MOVE_ROW) then
print_row_path(pos1,pos2)
print_col_path(pos1,pos2)
else
print_col_path(pos1,pos2)
print_row_path(pos1,pos2)
end if
print 'E'
end
function print_path(start, end : char)
begin
position pos1 ← get_pos(start)
position pos2 ← get_pos(end)
print_path_direction(pos1,pos2, FIRST_MOVE_ROW)
end
Où print_times_char(t,c) est une fonction qui imprime t fois le caractère c. J'ai défini deux "saveurs" d'impression de chemin, l'une imprimant les mouvements de ligne en premier et l'autre imprimant les mouvements de colonne en premier.
En supposant que les positions (6,2) et (6,3) sont interdites
Si nous ne sommes pas autorisés à utiliser les positions (6,2) et (6,3) alors :
- si 'A' ≤ début,fin ≤ 'X' ou 'Y' ≤ début,fin ≤ 'Z' : (6,2) ou (6.3) ne seront jamais utilisés dans le chemin.
- si 'A' ≤ start ≤ 'X' et 'Y' ≤ end ≤ 'Z' : pour s'assurer de ne pas utiliser les cellules interdites, imprimer d'abord les mouvements de colonnes.
- si 'A' ≤ end ≤ 'X' et 'Y' ≤ start ≤ 'Z' : cette fois, nous devons d'abord imprimer les mouvements de lignes.
En pseudo-code :
function print_path_wo_forbidden(start, end : char)
begin
position pos1 ← get_pos(start)
position pos2 ← get_pos(end)
if if 'A' ≤ start ≤ 'X' and 'Y' ≤ end ≤ 'Z' then
print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
else
print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
end if
end
Complexité
L'impression du chemin entre deux positions est clairement en O(1), donc pour une chaîne de longueur n nous pouvons construire un algorithme O(n).