- Molte volte nel testo dell'esercizio si specificano dei vincoli sull'input. Occorre verificarne sempre la veridicità. Nel caso in cui l'input inserito non rispetti il vincolo, stampare un messaggio di errore e chiederne il reinserimento, fino a quando non viene fornito un input valido. Ad esempio, se il programma *pippo.go* attende in input un numero pari, un possibile scenario potrebbe essere il seguente:
```console
$./pippo
Inserire un numero n pari:
3
Numero non valido
Inserire un numero n pari:
5
Numero non valido
Inserire un numero n pari:
2
```
- Se non vengono specificati vincoli sull'input, si può assumere che sia privo di errori
- Evitare di inserire stampe non richieste
- Ricordatevi di usare sempre `gofmt` per formattare correttamente il file
- Se un esercizio vi sembra troppo difficile da risolvere al primo colpo, provate a "scomporlo" in sottoproblemi più semplici e a risolverlo per passi
- mi raccomando date "nomi parlanti" alle variabili
## Continuo di ``tartaruga.go``
Riprendete l'esercizio ``tartaruga.go`` di due lezioni fa e modificate il programma in modo che venga evidenziata nella stampa il percorso seguito dalla tartaruga stessa. Riflettete bene su come modificare metodi / strutture dati utilizzate. In particolare, chiedetevi **dove** memorizzare il percorso seguito.
fmt.Print("\ncomandi:\n\n1 -> avanti\n2 -> indietro\n3 -> ruota a dx\n4 -> ruota a sx\n5 -> fai la cacca\n0 -> esci\n\n")
fori:=0;i<1;{
griglia(t,poops)
fmt.Print("comando: ")
fmt.Scan(&c)
switchc{
case1:
fmt.Print("n° di passi: ")
fmt.Scan(&p)
ifp>l{
fmt.Println("\nè una tartaruga, vacci piano\n")
}elseifp<0{
fmt.Println("\ndai, fai il serio\n")
}else{
forward(p,&t)
status(t,poops)
}
case2:
fmt.Print("n° di passi: ")
fmt.Scan(&p)
ifp>l{
fmt.Println("\nè una tartaruga, vacci piano\n")
}elseifp<0{
fmt.Println("\ndai, fai il serio\n")
}else{
backward(p,&t)
status(t,poops)
}
case3:
right(&t)
status(t,poops)
case4:
left(&t)
status(t,poops)
case5:
varflagbool
flag=true
fori:=0;i<len(poops);i++{
ifpoops[i].x==t.x&&poops[i].y==t.y{
flag=false
break
}
}
ifflag{
makePoop(t,&poops)
status(t,poops)
}else{
fmt.Println("\nl'hai già fatta qua\n")
}
case0:
fmt.Println("\nadios\n")
i+=1
default:
fmt.Println("\ncomando non valido\n")
}
}
}
```
## Digressione "make"
```go
//scrivere un programma che appenda elementi ad una slice, e che stampi a distanza di un intervallo di tempo
//i vari valori che la slice assume nel tempo
packagemain
import(
"fmt"
"math/rand"
"time"
)
funcmain(){
vars[]int
now:=time.Now().UnixNano()
rand.Seed(now)
//d,_=time.ParseDuration("1.5s")
//fmt.Println(s)
fori:=0;i<10000;i++{
//n:=rand.Int()%100
s=append(s,155)
fmt.Print(len(s),cap(s),": ");
fmt.Println(time.Now().UnixNano()-now)
now=time.Now().UnixNano()
}
}
```
### Esercizio 1 (`fattoriale.go`)
Scrivere un programma che, preso un intero positivo in input da linea di comando, ne restituisce il fattoriale attraverso una funzione ricorsiva.
##### Esempio di esecuizione
```console
$./fattoriale 5
120
```
### Soluzione 1
```go
packagemain
import(
"fmt"
"os"
"strconv"
)
funcfactorial(nint)int{
ifn==0||n==1{
return1
}
return(n*factorial(n-1))
}
funcmain(){
n,err:=strconv.Atoi(os.Args[1])
iferr!=nil{
fmt.Println("inserisci un intero!")
os.Exit(0)
}
fmt.Println(factorial(n))
}
```
### Soluzione 2 (parzialmente corretta)
```go
packagemain
import"fmt"
funcfattoriale(numint)int{
ifnum<=1{// idea parzialmente buona per non andare in loop
returnnum
}
returnnum*fattoriale(num-1)
}
funcmain(){
varnumint
fmt.Println("inserisci num")
fmt.Scan(&num)
fmt.Println("fattoriale: ",fattoriale(num))
}
```
Il problema qui è che se gli passo `0` come input, come riusltato ottengo `0`, ma `0! = 1`. Però con l'`if` mi evito di entrare in loop con i numeri negativi. Ovviamente se in input ho un numero negativo, in output non ho il suo fattoriale.
### Soluzione 3 (stramba in senso negativo)
```go
packagemain
import"fmt"
funcfact(nint)int{
//for i:=0;i<n;i++{ // inutile (non lo completa mai)
fmt.Println("pre if: ",n);
ifn==1{
fmt.Println("=1",n);
returnn
}else{
fmt.Println("!=1",n);
returnn*fact(n-1)
}
//}
returnn
}
funcmain(){
varnint
fmt.Scan(&n)
res:=fact(n)
fmt.Println(res)
}
```
(già commentate via le righe inutili, per cui torna una soluzione normale)
### Esercizio 2 (`palindromo.go`)
Scrivere un programma che, preso come input un file contenente un testo, verifica se questo sia palindromo.
Mi raccomando ragionate bene sull'assunzione ricorsiva e sul controllo che dovete fare per terminare la ricorsione.
*Suggerimento* prima di risolvere l'esercizio con un testo completo, provate a risolverlo quando il testo contiene una sola parola.
##### Esempio di esecuizione
```shell
$ ./palindromo input_palindromo.txt
si
```
dove `input_palindromo.txt` è, per esempio:
```
Da ore Simone rasa mare.
È capace e va!
Nauta laido,
a ira leggeri ami meri sollevi là!
E là è Dio! Suol ridarti amore!
Pietro con Gesù segnò cortei.
Però mai tradirlo! (uso ideale!)
A livello sì remi:
mai regge l’aria; odia la tua nave!
E capace era, ma s’arenò! Misero!
Ad
```
Notare che i segni di punteggiatura sono da ignorare, come anche gli accenti sulle parole.