L'input per questo codice é un comando composto da una direzione (Nord, Sud, Est, Ovest) e da un numero di passi. Il codice muove il robot nella direzione indicata un passo alla volta. A ogni passo marca la cella attraversata come "pulita" facendo attenzione a quelle giá pulite in precedenza cosi alla fine ha il conto totale delle celle pulite senza doppioni.
La 1^ implementazione é di
8 righe, ha un unico for. Per eseguire ogni linea di codice almeno una volta basta
1 test. Ecco la spiegazione:
- Alla riga 1 la direzione vine trasfomata in vettore, ad esempio Nord é (0,1), grazie a un operatore di conversione da Direction a Point che internamente usa un Dictionary per mappare ogni direzione con il suo vettore senza bisogno di IF.
- Sempre alla riga 1 il tipo Point implementa anche la moltiplicazione per intero cosi si puó calcolare anche il verso e non serve IF per spostamenti in avanti o indietro.
- La riga 6 calcola lo spostamento come somma di vettori, un algoritmo lineare che non ha bisogno di IF per le diverse direzioni e versi.
- La riga 7 marca la cella pulita con una operazione idempotente, cioé la salva in un Dictionary che non tiene doppioni, quindi non serve IF per testare se la cella é giá pulita.
1: Vector2D moveDirection = (Vector2D)moveCommand.Direction * Math.Sign(moveCommand.Steps);
2: int distance = Math.Abs(moveCommand.Steps);
3:
4: for (int cleanOperation = 1; cleanOperation <= distance; ++cleanOperation)
5: {
6: _currentPosition = _currentPosition + moveDirection;
7: _office.SetPlaceCleaned(_currentPosition);
8: }
La 2^ implementazione é di
87 righe, ha uno switch con 4 casi, dentro un for nidificato per ogni caso e dentro 2 if nidificati. Per eseguire ogni linea di codice almeno una volta servono
12 test diversi.
1: switch (direzione)
2: {
3: case 'N':
4: for (int i = 0; i < passi; i++)
5: {
6: if (Y_ATTUALE + 1 > FLOOR_UPPER_BOUND_LENGTH)
7: {
8: Y_ATTUALE = FLOOR_UPPER_BOUND_LENGTH;
9: break;
10: }
11: else
12: {
13: if (!cellePulite.ContainsKey(string.Format("{0}{1}", X_ATTUALE, Y_ATTUALE + 1)))
14: {
15: cellePulite.Add(string.Format("{0}{1}", X_ATTUALE, Y_ATTUALE + 1), new Coordinate(X_ATTUALE, ++Y_ATTUALE));
16: }
17: else
18: {
19: ++Y_ATTUALE;
20: }
21: }
22: }
23: break;
24: case 'S':
25: for (int i = 0; i < passi; i++)
26: {
27: if (Y_ATTUALE - 1 < FLOOR_LOWER_BOUND_LENGTH)
28: {
29: Y_ATTUALE = FLOOR_LOWER_BOUND_LENGTH;
30: break;
31: }
32: else
33: {
34: if (!cellePulite.ContainsKey(string.Format("{0}{1}", X_ATTUALE, Y_ATTUALE - 1)))
35: {
36: cellePulite.Add(string.Format("{0}{1}", X_ATTUALE, Y_ATTUALE - 1), new Coordinate(X_ATTUALE, --Y_ATTUALE));
37: }
38: else
39: {
40: --Y_ATTUALE;
41: }
42: }
43: }
44: break;
45: case 'E':
46: for (int i = 0; i < passi; i++)
47: {
48: if (X_ATTUALE - 1 < FLOOR_LOWER_BOUND_WIDTH)
49: {
50: X_ATTUALE = FLOOR_LOWER_BOUND_WIDTH;
51: break;
52: }
53: else
54: {
55: if (!cellePulite.ContainsKey(string.Format("{0}{1}", X_ATTUALE - 1, Y_ATTUALE)))
56: {
57: cellePulite.Add(string.Format("{0}{1}", X_ATTUALE - 1, Y_ATTUALE), new Coordinate(--X_ATTUALE, Y_ATTUALE));
58: }
59: else
60: {
61: --X_ATTUALE;
62: }
63: }
64: }
65: break;
66: case 'W':
67: for (int i = 0; i < passi; i++)
68: {
69: if (X_ATTUALE + 1 > FLOOR_UPPER_BOUND_WIDTH)
70: {
71: X_ATTUALE = FLOOR_UPPER_BOUND_WIDTH;
72: break;
73: }
74: else
75: {
76: if (!cellePulite.ContainsKey(string.Format("{0}{1}", X_ATTUALE + 1, Y_ATTUALE)))
77: {
78: cellePulite.Add(string.Format("{0}{1}", X_ATTUALE + 1, Y_ATTUALE), new Coordinate(++X_ATTUALE, Y_ATTUALE));
79: }
80: else
81: {
82: ++X_ATTUALE;
83: }
84: }
85: }
86: break;
87: }