Track
/
Go
Go
/
Esercizi
/
Scacchiera
Scacchiera

Scacchiera

Esercizio di apprendimento

Introduzione

In Go, puoi iterare su uno slice usando for e un indice, oppure puoi usare range. range ti permette anche di iterare su una map.

Ogni iterazione restituisce due valori: l'indice o la chiave, e una copia dell'elemento in quella posizione.

Iterare su uno slice

Facile come bere un bicchier d'acqua: i cicli su uno slice sono ordinati come ci si aspetta.

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30

Iterare su una map

Iterare su una map presenta un nuovo problema. Ora l'ordine è casuale.

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
  fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
Note

Può sembrare che l'output qui sopra sia errato: ci si aspetterebbe che la prima coppia chiave/valore della dichiarazione della map, 9 10, sia la prima a essere stampata, e non l'ultima. Tuttavia, le map sono per natura prive di ordine: non esiste una prima né un'ultima coppia chiave/valore. Per questo, quando si iterano le voci di una map, l'ordine in cui le voci vengono visitate è casuale e non segue alcuno schema preciso. Ciò significa che l'output qui sopra è possibile, ma potrebbe differire da quello che ottieni se provi a eseguirlo tu. Per saperne di più, consulta Go Language Spec: range clause.

Iterazione con chiave o valore omessi

In Go, una variabile non utilizzata genera un errore in fase di compilazione. A volte ti serve solo il valore, come nel primo esempio:

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(x)
}
// Go build failed: i declared but not used

Puoi sostituire i con _, cosa che indica al compilatore che non usiamo quel valore:

xi := []int{10, 20, 30}
for _, x := range xi {
  fmt.Println(x)
}
// outputs:
// 10
// 20
// 30

Se vuoi stampare solo l'indice, puoi sostituire x con _, oppure omettere del tutto la dichiarazione:

xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
  fmt.Println(i)
}
// outputs:
// 0
// 1
// 2

Definire i tipi

Una definizione di tipo crea un nuovo tipo con un nome, distinto da ogni altro tipo, anche da uno con lo stesso tipo sottostante.

type File []bool

File qui si riferisce a una singola colonna verticale su una scacchiera, comunemente etichettata da A a H. Ogni casella di questa colonna è rappresentata da un valore booleano che indica se è occupata o no. Ora che File è definito, possiamo usarlo all'interno di altre definizioni:

type Chessboard map[string]File

board := Chessboard{
    "A": File{true, false, true},
    "B": File{false, true, false},
}

Chessboard mappa gli identificatori delle colonne su valori File. Ogni File è uno slice di booleani che rappresenta le caselle di una colonna della scacchiera. Senza queste definizioni di tipo, board sarebbe una map[string][]bool, il che renderebbe più difficile capire cosa stiamo rappresentando.

Istruzioni

Da appassionato di scacchi, ti piacerebbe scrivere la tua versione del gioco. Certo, online esistono già moltissime implementazioni degli scacchi, ma la tua sarà unica!

Ogni casella della scacchiera è identificata da una coppia lettera-numero:

  • Le righe orizzontali di caselle, chiamate «traverse», sono numerate da 1 a 8.
  • Le colonne verticali di caselle, chiamate «colonne», sono contrassegnate da A a H.
   A B C D E F G H
 8 # _ _ _ # _ _ # 8
 7 _ _ _ _ _ _ _ _ 7
 6 _ _ _ _ # _ _ # 6
 5 _ # _ _ _ _ _ # 5
 4 _ _ _ _ _ _ # # 4
 3 # _ # _ _ _ _ # 3
 2 _ _ _ _ _ _ _ # 2
 1 # _ _ _ _ _ _ # 1
   A B C D E F G H

1. Data una scacchiera e una colonna, conta quante caselle sono occupate

Implementa la funzione CountInFile(board Chessboard, file string) int. Deve contare il numero totale di caselle occupate iterando su una mappa. Deve restituire un numero intero. Deve restituire un conteggio pari a zero (0) se la colonna indicata non è presente nella mappa.

CountInFile(board, "A")
// => 3

2. Data una scacchiera e una traversa, conta quante caselle sono occupate

Implementa la funzione CountInRank(board Chessboard, rank int) int. Deve contare il numero totale di caselle occupate iterando sulla traversa indicata. Deve restituire un numero intero. Deve restituire un conteggio pari a zero (0) se la traversa indicata non è valida (non è compresa tra 1 e 8, estremi inclusi).

CountInRank(board, 2)
// => 1

3. Conta quante caselle sono presenti nella scacchiera indicata

Implementa la funzione CountAll(board Chessboard) int. Deve contare quante caselle sono presenti nella scacchiera e restituire un numero intero. Dato che non devi controllare il contenuto delle caselle, prova a usare range omettendo sia index che value.

CountAll(board)
// => 64

4. Conta quante caselle sono occupate nella scacchiera indicata

Implementa la funzione CountOccupied(board Chessboard) int. Deve contare quante caselle sono occupate nella scacchiera. Deve restituire un numero intero.

CountOccupied(board)
// => 15
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Go Exercism

Vuoi iniziare Scacchiera?

Iscriviti a Exercism per imparare e padroneggiare Go con 34 concetti166 esercizi e il mentoring di persone reali, tutto gratis.