# sorgenti (inclusi nomi sbagliati) consegnati: 218
# quanti di ogni esercizio:
```
15 quadrati.go
14 es7.go
14 es2.go
13 es12.go
13 es10.go
12 es8.go
11 array.go
10 punto_bis.go
10 ordini.go
9 countdown.go
9 contaLettere.go
8 extractions.go
7 usaStandard.go
7 polinomio.go
7 estraiData_bis.go
7 dado_bis.go
6 stampaAlternata.go
5 usoLeSlice.go
4 giornoSettimana.go
4 conta_cifre.go
4 carte.go
3 strings2slice.go
3 scambio.go
3 es6.go
3 es5.go
3 es4.go
3 es3.go
2 puntatori.go
2 clessidra.go
1 usastandard.go
1 puntatore2.go
1 estraiDATA_bis.go
1 es9.go
1 es11.go
1 es1.go
1 black_jack.go
```
---
# Esercizi Go
## Note iniziali
- convenzione nomi file (dir, file, mod: nomi uguali)
- nella dir dell'esercizio, lanciare il comando:\
```go mod init <nome programma senza estensione>```
## Richiami sulle mappe
### Dichiarazione di una mappa (viene creata una mappa "zero-value", cioè nil)
Sintassi:
```go
var mapName map[keyType]valueType
```
Esempio:
```go
var map1 map[string]int
```
**Nota**. A differenza delle slice, una mappa deve essere inizializzata (vedi qui sotto come) prima di poter aggiungervi elementi, altrimenti si ottiene un errore run-time:\
<tt>panic: assignment to entry in nil map</tt>
### Inizializzazione di una mappa
Sintassi:
```go
mapName := make(map[keyType]valueType)
```
o anche:
```go
mapName := map[keyType]valueType{} // tra {} ci può essere una lista di coppie chiave-valore
Inserimento o aggiornamento di un elemento in una mappa m (si fanno nello stesso modo, non occorre controllare se la chiave c'era già):
```go
m[key] = elem
```
Accesso a un elemento di una mappa:
```go
elem = m[key]
```
Cancellazione di un elemento da una mappa:
```go
delete(m, key)
```
Verifica della presenza di una chiave in una mappa:
```go
element, ok = mappa[key] //se key c'è in mappa, ok è true; altrimenti ok è false e elemt è zero-value
```
Per verificare se due mappe sono uguali, vedete la funzione `DeepEqual` del package `reflect`.
### Usi delle mappe
- per **contare**: `map[Type]int`
ad esempio quante occorrenze di ogni stringa in un testo: `map[string]int`
- per creare **cataloghi**: `map[string/int] string/struct`
- per creare **dizionari**: `map[string]string`
- per **raggruppare** valori/oggetti in base a una caratteristica: `map[tipo caratteristica][]tipo dei valori/oggetti`, quindi una mappa chiave - slice.
- ecc.
---
## Esercizi sulle mappe
### Lunghezze (mappe)
Scrivere un programma lunghezze.go che legge riga per riga un testo da standard input (potete usare la ridirezione), terminato da EOF, e stampa quante parole ci sono di lunghezza 1, quante di lunghezza 2, ecc.
che aggiorna la mappa dei conteggi e che deve essere usata dal main.
nomefile: lunghezze.go
### Vocali (mappe)
Scrivere un programma vocali.go che analizza un testo e conta le occorrenze delle vocali (sia minuscole che maiuscole, ma non le accentate) nel testo e stampa, ma solo per le vocali presenti nel testo, il numero di volte che le vocali stesse sono presenti nel testo.
In particolare il programma è dotato di:
- una funzione
```
func contaVocali(s string, vocali map[rune]int)
```
per contare le occorrenze delle diverse vocali (sia minuscole che maiuscole - vedi es sotto) in tutte le stringhe che le vengono passate. La funzione, data una stringa s e una mappa vocali, aggiorna opportunamente la mappa vocali aggiungendo eventuali vocali non ancora presenti / incrementandone i valori.
Nota: per individuare le vocali e aggiornare la mappa <tt>vocali</tt> usate uno switch con un solo case o un if, sempre con un solo caso, che ovviamente sarà parametrico nelle vocali.
- una funzione
```
func main()
```
che legge una riga di testo da standard input e produce una mappa tra vocali presenti nel testo e il numero delle loro occorrenze nel testo, e la stampa.
#### Esempio
Se l'input è:
```
jdhkas c'è dkasjhkdjashkdh askdh ksah @@@ €€€ ### Ħ wi) Ø qwqwe qwyewquteuqwte q 312312 2312wweqe €łłŧŧŧŧŧ sdasdas AA JKJLKLJLKJ LIIIIII u ù aeiou AEIO
```
L'output è (salvo l'ordine di stampa):
```
o : 1
E : 1
u : 4
e : 7
A : 3
I : 7
O : 1
a : 8
i : 2
```
Come si potrebbero stampare le vocali con le loro occorrenze in ordine alfabetico?
Scrivere una seconda versione vocali_bis.go che produce l'output in ordine:
```
A : 3
E : 1
I : 7
O : 1
a : 8
e : 7
i : 2
o : 1
u : 4
```
nomefile: vocali.go
nomefile: vocali_bis.go
### Anagrammi (volendo mappe, ma anche slice)
Scrivere un programma anagrammi.go che legge due stringhe da linea di comando e valuta se le due stringhe sono una l'anagramma dell'altra (la seconda stringa è formata da una permutazione dei caratteri della prima)
In particolare il programma è dotato di:
- una funzione
```
func isAnagram(s1, s2 string) bool
```
che restituisce true se le due stringhe sono una l'anagramma dell'altra, false altrimenti
- una funzione
```
func main()
```
che legge due parole p1 e p2 da linea di comando e stampa uno dei due messaggi:
"p1 e p2 sono anagrammi" o "p1 e p2 non sono anagrammi"
NB: **che caratteristiche ha un anagramma?**
C'è in Go una struttura di dati (array, struct, slice, map) che
si presta a rappresentare i dati di una stringa s1 che servono
ad individuare se è un anagramma di un'altra stringa s2?
Se sì, quale e coma la uso? Se no, come imposto la soluzione?
In assenza di esattamente due parametri sulla linea di comando il programma stampa: `input errato`
nomefile: anagrammi.go
### NumToText (mappe)
Scrivere un programma num2text.go per convertire un numero intero non negativo nella sequenza delle parole corrispondenti alle sue cifre.
Il programma legge un intero non negativo da standard input, per ogni nuova (non incontrata finora) cifra del numero chiede il nome corrispondente (e alimenta un dizionario), e infine stampa la sequenza delle parole corrispondenti alle sue cifre.
Ad esempio, per il numero 203, il programma stampa:
```
due - zero - tre
```
#### Esempio di esecuzione
```
$ go run num2text.go
un numero: 622
parola per 2 ? due
parola per 6 ? sei
sei - due - due
```
nomefile: num2text.go
### Capoluoghi (mappe)
Scrivere un programma capoluoghi.go che legge da standard input (usate la ridirezione dal file [capoluoghi](Lab08/capoluoghi.csv)) una serie di informazioni sui capoluoghi organizzate su righe, nel seguente formato:
e memorizza Nome, Sigla, Regione, Superficie in modo sia possibile ottenere la stampa delle informazioni relative a capoluoghi, le cui sigle sono state passate da linea di comando.
Nome, Sigla, Regione sono stringhe; Popolazione,Superficie, Densità, Altitudine sono sempre int.
La prima riga è l'intestazione e le successive contengono i dati, separati da virgole, un riga per capoluogo.
Il programma deve essere dotato di una struct Capoluogo con campi Nome, Sigla, Regione, Superficie, in quest'ordine.
NB: discorso struct "ridondante in apparenza"
#### Esempio di esecuzione
```
$ ./capoluoghi MI < capoluoghi.csv
{MILANO MI LOM 1371498 181 7549 122}
```
nomefile: capoluoghi.go
### Regioni (mappe)
Scrivere un programma regioni.go che che legge da standard input (usate la ridirezione dal file [capoluoghi](Lab08/capoluoghi.csv)) una serie di informazioni sui capoluoghi di provincia organizzate su righe, nel seguente formato:
e memorizza nome e regione in modo che sia possibile ottenere la stampa della lista dei capoluoghi di provincia delle regioni i cui nomi sono stati forniti da linea di comando.
nomefile: regioni.go
### Posizioni parole (mappe)
Scrivere un programma posizioni_parole.go che legge una sequenza di stringhe da standard input e produce su standard output, per ogni stringa, la lista delle posizioni in cui essa compare nella sequenza (partendo dalla posizione 0).
Nota: per terminare l’input da tastiera, premere invio e la combinazione di tasti Ctrl D, che corrisponde a EOF (end of file) per lo standard input.
In caso di dubbi su come gestire la fine dell’input nel programma, consultare la documentazione della funzione Scan, funzione che, oltre a salvare i valori letti, restituisce dei valori.
Nel caso l'input non sia nè un numero nè un operatore nè
"q", il programma lo ignora (non occorre che segnali errore).
Per verificare se l'input è un numero, utilizzare la funzione
```go
val, err := strconv.ParseFloat(input, 64)
```
Nel caso err sia nil, l'input è un numero che verrà salvato
in val.
#### Esempio
```
$ go run RPN.go
Next? (+, -, *, /, q o un numero) 3
[3]
Next? (+, -, *, /, q o un numero) 5
[3 5]
Next? (+, -, *, /, q o un numero) 7
[3 5 7]
Next? (+, -, *, /, q o un numero) *
[3 35]
Next? (+, -, *, /, q o un numero) +
[38]
Next? (+, -, *, /, q o un numero) -
not enough data
[38]
Next? (+, -, *, /, q o un numero) q
```
Creare una seconda versione RPN2.go in cui l'espressione
da valutare sia fornita da linea di comando (os.Args)
invece che da standard input (cioe` tastiera).
In questo caso se l'espressione contiene moltiplicazioni,
l'asterisco va messo tra apici ('*') o tra virgolette ("*").
nomefile: RPN.go
### Progetto Black Jack (slice)
Riprendere il progetto del Black Jack, dove una carta
era una struct con i campi seme (string) e valore (string).
Definire una funzione main() per testare man mano le funzioni
che seguono.
Modificare la funzione mazzoPoker che crea e restituisce un
mazzo di 52 carte da poker, usando una slice invece che un array,
in modo da poter "distribuire" carte dal mazzo.
Modificare quindi anche la funzione mischia che, dato un mazzo di carte
(di dimensione arbitraria), lo rimescola in modo random
(occorre usare anche qui le slice).
Definire una funzione preleva che, dato un mazzo di carte,
restituisce la carta che si trova in cima e la toglie dal mazzo.
Implementare un simulatore di BJ
(https://it.wikipedia.org/wiki/Blackjack),
che consenta ad un giocatore singolo di giocare contro
il PC (che rappresenta il mazziere).
Utilizzare come mazzo due mazzi da poker.
nomefile: blackjack.go
---
## Esercizi supplementari
### Stats temperature (ripasso slice)
Scrivere un programma temperature.go che legge delle temperature (int) da tastiera e termina quando il valore letto è 999.
Il programma deve stampare:
- la media
- la mediana
- il numero di temperature sotto la media delle temperature stesse.
- le tre temperature più basse (se ci sono almeno 3 temperature)
- le tre temperature più alte (se ci sono almeno 3 temperature)
Nota 1: la mediana di un insieme di dati è data, nel caso ci sia un numero dispari di dati, dal dato centrale dei dati ordinati per valore (ad es. crescente), altrimenti dalla media dei due dati centrali.
Nota 2: Utilizzare la funzione `Ints(a []int)` del pacchetto `sort` per ordinare in modo crescente le temperature.
nomefile: temperature.go
### Appello (ripasso slice)
Scrivere un programma appello.go che legge da linea di comando una sequenza di nomi e li stampa in ordine alfabetico.
#### Esempio
```
$ go run appello.go Rita Carlo Matteo Ada
[Ada Carlo Matteo Rita]
```
Nota: Utilizzare la funzione `Strings(a []string)` del pacchetto `sort` per ordinare in modo crescente i nomi.
nomefile: appello.go
### Galleggianti (sfida per i più arditi)
Scrivete un programma galleggianti.go che legga da standard input due interi r, c, seguiti da una matrice di r righe e c colonne contenente lettere maiuscole e asterischi, e che stampi in output la matrice che si ottiene da quella in input mandando verso il basso le lettere e facendo "galleggiare" gli asterischi, cioè mandandoli verso l'alto.
Fornire in input una riga della matrice alla volta, e sfruttare la funzione `strings.Split(s, " ")` (vedi documentazione) per popolare le righe della matrice.
Si assuma che ogni riga di input contenga esattamente c caratteri, separati da spazi (non sono richiesti controlli in tal senso).