CAPITOLO 6.

Slides:



Advertisements
Presentazioni simili
Esercizio Usate il ciclo repeat until (controllo post condizionale) per simulare il prodotto N x M con M somme di N. Esempio: 5 x 3 equivale a fare 5 +5.
Advertisements

Programma: main() { istruzioni } ; assegnazione condizione ciclo istruzione: ;
Informatica 22/03/2012.
LS Tron Classe 4TC – as 2006/07 LORGANIZZAZIONE DEI PROGRAMMI UD. 8 p. 282.
PROGRAMMARE IN PASCAL (le basi)
Le funzioni UD. 8 – Lorganizzazione dei programmi p. 309 LS Tron 4TC 06/07.
3TC – 5/11/2010 Cicli while e do.. While Contatori e Totalizzatori.
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
Dipartimento di Matematica
Algoritmi e Programmazione
Informatica Generale Marzia Buscemi
Fondamenti di Informatica
ESERCITAZIONE N. 5 ESERCIZIO N. 1 Autore: Biagio Brattoli S I Corso.
INFORMATICA Strutture iterative
Introduzione agli algoritmi. Definizione Sistema di regole e procedure di calcolo ben definite che portano alla soluzione di un problema con un numero.
Iterazione enumerativa (for)
Algoritmi Politecnico di Milano
Università degli Studi di Bergamo Facoltà di Lingue e Letterature Straniere Facoltà di Lettere e Filosofia A.A Informatica generale 1 Appunti.
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
Corso di Laurea in Biotecnologie Informatica (Programmazione)
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab m-file m-file script script Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali.
MATLAB.
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Indipendenza lineare,
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Esercizi vari Esercizi.
Ricorsione e Debug.
Primo esercizio Scrivere un programma che legge da input
Programmazione Un programma descrive al computer, in estremo dettaglio, la sequenza di passi necessari a svolgere un particolare compito L’attività di.
Il linguaggio Fortran 90: 2. Istruzioni di Controllo
Introduzione alla programmazione lll
APPUNTI SUL LINGUAGGIO C
DAL PROBLEMA ALL'ALGORITMO Problemi e Programmi Paolo Amico
Somma = A + B start Stampa Somma Leggi A,B stop Sub SOMMA( ) Dim A, B as Integer A = InputBox("Immetti un numero") B = InputBox(Immetti un secondo numero)
Fondamenti di Informatica I a.a Il linguaggio C Il controllo di flusso La selezione condizionale Listruzione switch I cicli Le istruzioni break,
Procedure e funzioni nei linguaggi di alto livello Lab Programmazione - turno /2006.
Algoritmi su Tipi Semplici
Istruzioni Decisionali
Istruzioni Iterative Nicola Fanizzi
Strutture di controllo in C -- Flow Chart --
Problema Ci sono 5 signore nel parco. Ognuna di loro ha 1 figlio. Ogni bambino ha 10 figurine di calciatori, per un totale quindi di 50 figurine. Questi.
OPERAZIONI CON STRINGHE Le operazioni più interessanti da fare, per ora, con le stringhe sono: determinare la lunghezza della stringa, cioè quanti caratteri.
CAPITOLO 7.
FILE TESTO OUTPUT INPUT + DATI PROGRAMMA OUTPUT INPUT PROGRAMMA CARICAMENTO DATI FILE DATI.
CAPITOLO 5.
Lezione 2 Programmare in ASP
TURBOPASCAL …. ripassiamo - prof. V. Riboldi -.
PROBLEMA ALGORITMO PROGRAMMA LINGUAGGI di PROGRAMMAZIONE
Cicli in Fortran I cicli consentono di eseguire una sequenza di istruzioni più di una volta due tipi: Cicli iterativi Cicli while.
Programmare in Visual Basic
I numeri di Fibonacci.
Problema: come dividere due numeri
PERMETTEDI INDIVIDUARE
ND-partizione (A) n   A  somma  0 M  1/2 (  a i ) for i  1 to n do S[i]  choice ({true, false}) if S[i] then somma  somma + a i if somma > M then.
Programmazione Strutturata
TURBOPASCAL …. ripassiamo - prof. V. Riboldi -.
RISOLUZIONE DI EQUAZIONI
Ripetizione La vera potenza dei programmi per computer risiede nella capacità di ripetere lo stesso calcolo o sequenza di istruzioni più volte, ogni volta.
Il linguaggio Fortran 90: 3. Procedure e Funzioni
TURBOPASCAL L’iterazione - prof. V. Riboldi -.
Il ciclo while.  Permette di ripetere un blocco di istruzioni fino a quando non si verifica un determinato evento  Il ciclo while può essere realizzato.
R 255 G 211 B 8 R 255 G 175 B 0 R 127 G 16 B 162 R 163 G 166 B 173 R 104 G 113 B 122 R 234 G 234 B 234 R 175 G 0 B 51 R 0 G 0 B 0 R 255 G 255 B 255 Supporting.
PROVA INTERCORSO MOD.B a.a RICORSIONE ESERCIZI A1.1-A1.6.
Lez 4 (13/14)Elementi di Programmazione1 Strutture di controllo 2.
Tecnologie Informatiche ed Elettroniche per le Produzioni Animali
RossiUgo /8796 BianchiCarlo /8746 II I Sia dato un file di testo riguardante un insieme di studenti di cui è.
Informatica e Informatica di Base
Ciclo for nei linguaggi di programmazione. Nei linguaggi di programmazione, il ciclo for è una struttura di controllo iterativa che determina l'esecuzione.
Samuele Marino. Cos’è il Repeat Until?  In Pascal, il Repeat Until è un ciclo che consiste nel ripetere (Repeat) una o più istruzioni fino a quando (Until)
Strutture di controllo
Algoritmi Avanzati a.a.2011/2012 Prof.ssa Rossella Petreschi Interconnessione tramite reti Lezione n°6.
Transcript della presentazione:

CAPITOLO 6

COME FARE ESEGUIRE AD UNA MACCHINA ISTRUZIONI RIPETITIVE ? WHILE …….. DO Un ciclo (loop) è una istruzione che permette di far eseguire, in maniera ripetitiva, un blocco di istruzioni che la seguono un numero prefissato di volte.

WHILE Contatore <= N DO Contatore:=Contatore+1 REGOLE SINTATTICHE PER WHILE ….. DO Espressione per il controllo del ciclo Corpo del ciclo WHILE …. DO espressione booleana DO WHILE istruzioni WHILE Contatore <= N DO Contatore:=Contatore+1

Precondizioni Invariante di ciclo WHILE Contatore <= N DO Contatore:=Contatore+1 postcondizioni

ESEMPIO Somma:=0; Contatore:=0; WHILE Contatore>=5 DO BEGIN Contatore:=Contatore+1; Somma:=Somma+Contatore; writeln(Contatore:5, Somma:5) END; writeln(‘FINE’); Passo di computazione Contatore Somma 0 0 0 1 1 1 2 2 3 3 3 6 4 4 10 5 5 15

ALTRO ESEMPIO Passo di computazione Contatore Somma Numero read(Numero); WHILE Numero>0 DO BEGIN Contatore:=Contatore+1; Somma:=Somma+Numero; read(Numero) END; readln; writeln(Numero:1,’ ‘,Somma:1,‘ ‘,Contatore:1); Passo di computazione Contatore Somma Numero entrata nel loop 0 0 3 1 1 7 5 2 2 12 0 3 3 12 6 4 4 18 -2 uscita dal loop 4 18

ALTRO ESEMPIO Passo di computazione Passo Numero Contatore Somma WHILE Passo<>5 DO BEGIN Passo:= Passo+1; read(Numero); IF Numero<=0 THEN Contatore:=Contatore+1 ELSE Somma:=Somma+Numero END; readln; writeln(Somma:1,‘ ‘,Contatore:1); ALTRO ESEMPIO Passo di computazione Passo Numero Contatore Somma entrata nel loop 0 3 0 3 1 1 -2 1 3 2 2 -4 2 3 3 3 10 2 13 4 4 0 3 13 uscita dal loop 5 0 3 13

Esercizio dal libro pag.214 n.5

Pseudo Codice generale per i cicli precondizioni Inizializza i valori di partenza Esegui il processo di ciclo Usa i valori venuti fuori dal ciclo ciclo postcondizioni Un evento è una istruzione che una volta eseguita all’interno del ciclo cambia una parte dello stato del programma Un evento di uscita è un evento che all’interno del ciclo permette l’uscita dal programma

Esempio precondizioni postcondizioni Somma:=0; Contatore:=0; read(Numero); WHILE Numero>0 DO BEGIN Contatore:=Contatore+1; Somma:=Somma+Numero; read(Numero) END; readln; writeln(Numero:1,’ ‘,Somma:1,‘ ‘,Contatore:1); precondizioni postcondizioni IF Contatore <>0 THEN writeln(‘La media dei ‘,Contatore:5,’ valori introdotti e’’ ‘, ’ ‘,Somma/ Contatore:4:2); ELSE writeln(‘’Il primo numero introdotto e’’ negativo’);

Alcuni algoritmi di base risolti usando i Cicli (Loops) Conteggio sequenziale di eventi Pseudo codice ContatoreEventi  0 introduci ValoreEvento WHILE ValoreEvento rappresenta un evento da valutare DO ContatoreEventi  ContatoreEventi + 1 Somma:=0; Contatore:=0; read(Numero); WHILE Numero>0 DO BEGIN Contatore:=Contatore+1; Somma:=Somma+Numero; read(Numero) END; readln; writeln(Numero:1,’ ‘,Somma:1,‘ ‘,Contatore:1);

Conteggio di eventi selezionati Pseudo codice ContatoreEventi  0 WHILE ci sono altri eventi da valutare DO introduci ValoreEvento IF ValoreEvento è un evento significativo THEN ContatoreEventi  ContatoreEventi + 1 Somma:=0; Contatore:=0; Passo:=0; WHILE Passo<>5 DO BEGIN Passo:= Passo+1; read(Numero); IF Numero<=0 THEN Contatore:=Contatore+1 ELSE Somma:=Somma+Numero END; readln; writeln(Somma:1,‘ ‘,Contatore:1);

Accumulazione di eventi Pseudo codice Somma  0 WHILE ci sono altri eventi da valutare DO introduci ValoreEvento Somma  Somma + ValoreEvento Può dipendere dal valore di Somma o da quello di ValoreEvento Accumulazione di eventi selezionati Pseudo codice Somma  0 WHILE ci sono altri eventi da valutare DO introduci ValoreEvento IF ValoreEvento è un evento significativo THEN Somma  Somma + ValoreEvento

Meccanismi di Entrata/Uscita dai Cicli Esecuzione di un numero predeterminato di passi Passo:=0; WHILE Passo<>N DO Passo:=Passo+1 altre istruzioni Controllo con un evento sentinella introduci ValoreEvento WHILE ValoreEvento non è un evento terminale DO elabora ValoreEvento

Commentare questo programma PROGRAM TestLoop(input,output); VAR Indice,N:integer; BEGIN N:=10; Indice:=0; WHILE Indice<N DO writeln('Passo ',Indice:5,'N= ',N:5); N:=N*2-1; Indice:=N-1; readln END; END.

Alcuni operatori e i loro complementi Operatore Esempio Complemento Esempio < Passo<5 >= Passo>=5 <= Num<=0 > Num>0 = Passo=10 <> Passo<>10 > Num>0 <= Num<=0 >= Num>=0 < Num<0

Diagramma di flusso del ciclo WHILE istruzioni no si Eseguo il ciclo? Diagramma di flusso del ciclo WHILE

Domande da porsi per l’uso dei cicli Quale degli algoritmi sopra descritti bisogna usare? Quali sono le condizioni di entrata/uscita? Quale è l’istruzione di inizializzazione supposto sia necessaria? Quali sono le istruzioni che il ciclo deve eseguire ripetutamente? Quali sono le istruzioni, se ce ne sono, da eseguire al termine del ciclo?

Problema 6.2 Scrivere un programma per mostrare la media dei primi 10 numeri interi positivi introdotti. Input/Output 40 50 60 -10 -20 90 90 50 -20 50 70 90 -20 80 -70 80 20 La media dei primi 10 interi positivi è 58.0

Primo pseudo codice Somma  0 Conta  0 WHILE Conta<>10 DO Conta  Conta + 1 leggi i valori solo se positivi e mettili in Numero Somma  Somma + Numero mostra il valore di Somma/10 read(Numero) WHILE Numero <=0 DO PROGRAM Somma10NumeriPositivi(input,output); VAR Somma, Numero, Conta: integer; BEGIN Somma:=0; Conta:=0; WHILE Conta<>10 DO Conta:=Conta+1; read(Numero); WHILE Numero <= 0 DO Somma:=Somma+Numero; END; write(‘La media dei primi 10 numeri positivi è: ‘,Somma/10:3:1) END.

In generale per realizzare un algoritmo che sulla base del valore di un determinato evento esegua o meno delle istruzioni possiamo scrivere: Pseudo codice Introduci ValoreEvento WHILE ValoreEvento non rappresenta la condizione voluta DO

Problema 6.3 Scrivere un programma per mostrare la somma dei primi 50 numeri interi consecutivi fra 1 e 50. Mostrare la somma ogni 5 numeri. Conteggio Somma 5 15 10 55 15 120 20 210 ….. ….. 50 1275

Conta MOD 5 = 0 Mostra intestazioni Somma  0 Conta  0 WHILE Conta<>50 DO Conta  Conta + 1 Somma  Somma + Conta IF Conta è un multiplo di 5 THEN mostra Conta, Somma Conta MOD 5 = 0

PROGRAM MostraSomme(output); {mostra la somma dei primi 50 interi positivi ogni 5 valori} VAR Somma, Conta: integer; BEGIN writeln(‘CONTA ‘:10, ‘SOMMA ‘:10); writeln(‘---------- ‘:10, ‘------------ ‘:10); Somma:=0; Conta :=0; WHILE Conta <> 50 DO Conta:= Conta+1; Somma:=Somma+Conta; IF Conta MOD 5 = 0 THEN writeln(Conta :10, Somma :10); END END.

Esiste una maniera diversa per ottenere questo stesso risultato ? Si noti che la somma di tutti i numeri tra 1 e N è data dalla espressione: Somma=N*(N+1)/2. Il programma potrebbe quindi trasformarsi così: PROGRAM MostraSomme(output); {mostra la somma dei primi 50 interi positivi ogni 5 valori} VAR Somma, Conta: integer; BEGIN writeln(‘CONTA ‘:10, ‘SOMMA ‘:10); writeln(‘---------- ‘:10, ‘------------ ‘:10); Somma:=0; Conta :=0; WHILE Conta <> 50 DO Conta:= Conta+1; Somma:=Somma+Conta; IF Conta MOD 5 = 0 THEN writeln(Conta :10, Somma :10); END END. PROGRAM MostraSomme2(output); {mostra la somma dei primi 50 interi positivi ogni 5 valori} VAR Somma, Conta: integer; BEGIN writeln(‘CONTA ‘:10, ‘SOMMA ‘:10); writeln(‘---------- ‘:10, ‘------------ ‘:10); Somma:=0; Conta :=5; WHILE Conta <= 50 DO Somma:=Conta*(Conta+1) DIV 2; writeln(Conta :10, Somma :10); Conta:= Conta+5; END END.

Per tutte le possibili combinazioni dei valori di 1 e 0 assegnati LE COMBINAZIONI Per tutte le possibili combinazioni dei valori di 1 e 0 assegnati alle variabili a, b, c, d determinare il valore della funzione: ((ab)Vc) d Per generare tutte le possibili combinazioni con ripetizioni dei valori di 1 e 0 su N posti è sufficiente scrivere i numeri binari da 0 a 2N-1 Per N=3 si ha 000 001 010 011 100 101 110 111 Per generare tutte le possibili combinazioni con ripetizioni di K valori diversi su N posti è sufficiente scrivere i numeri in base K da 0 a 2N-1 Per K=3 e N=3 si ha (in totale sono 33 =27) 001 002 010 011 012 020 021 022 100 101 102 110 111 112 120 121 122 200 201 202 210 211 212 220 221 222

Si prendano come oggetti da combinare i numeri da 0 a N-1. Input: K, N ESERCIZIO Scrivere un programma che generi tutte le combinazioni con ripetizioni di K oggetti su N posti. Si prendano come oggetti da combinare i numeri da 0 a N-1. Input: K, N Output: le combinazioni con ripetizioni (combina)

UN ACCENNO ALLE PERMUTAZIONI Dati tre oggetti A B C in quante maniere diverse posssono combinarsi tra loro? ABC ACB BAC BCA CAB CBA Per calcolare il numero di permutazioni in funzione del numero di oggetti proviamo a costruire le permutazioni dati 4 oggetti. Prendiamo il primo oggetto A 1 Aggiungiamo a destra e a sinistra B  AB BA (1*2) Per ogni coppia generata aggiungiamo C in tutte le tre possibili posizioni ABC ACB BAC BCA CAB CBA (1*2*3) Per ogni tripla generata aggiungiamo D in tutte le quattro possibili posizioni ABCD ABDC ADBC DABC ACBD ACDB ADCB DACB BACD BADC BDAC DBAC BCAD BCDA BDCA DBCA CABD CADB CDAB DCAB CBAD CBDA CDBA DCBA (1*2*3*4) Se gli oggetti sono N allora il numero delle possibili permutazioni è pari a 1*2*3*……….*N

Si definisce fattoriale di un numero N il prodotto di tutti i numeri interi fra 1 e N: 0 1 1 1 2 2 3 6 -------------------- 10 3.628.800

PROGRAM Fattoriale10(output); {Mostra il fattoriale di 10} VAR Prod, Conta: real; BEGIN writeln(‘N ’:15,’N! ’:15); writeln(‘-- ’:15,’-- ’:15); Conta:=0; Prod:=1; WHILE Conta <>10 DO Conta:=Conta+1; Prod:=Prod*Conta; writeln(Conta:15,Prod:15) END END. Condizione di entrata Condizione di uscita

Esempio di input/output Problema 6.5 Supponiamo di dover prendere decisioni sull’acquisto di un’azione. Per fare questo l’agente di cambio decide sulla base dell’andamento giorno per giono dell’azione stessa. Assegnato allora un intervallo di tempo in giorni, introduciamo il prezzo dell’azione giorno per giorno. Introduciamo un contatore che contiene il numero di giorni nei quali l’azione è aumentata rispetto al giorno precedente e un contatore nel quale registriamo i giorni nei quali è calata. Non registriamo i giorni in cui l’azione è rimasta invariata. Esempio di input/output 1 2 3 4 5 6 7 8 9 10 37.25 37.50 38.00 37.75 37.50 38.00 38.00 38.25 38.75 38,25 GiorniInSalita=5 GiorniInDiscesa=3

Pseudo codice introduci NumeroGiorniTotale inizializza GiorniInSalita=0 GiorniInDiscesa=0 inizializza i valori di Giorno, GiornoPrima, ValoreOggi WHILE Giorno <> NumeroGiorniTotale DO Giorno  Giorno + 1 aggiorna i valori di GiornoPrima, ValoreOggi IF ValoreOggi < GiornoPrima THEN GiorniInDiscesa= GiorniInDiscesa+1 ELSE IF ValoreOggi > GiornoPrima THEN GiorniInSalita= GiorniInSalita+1 Giorno  1 readln(ValoreOggi) GiornoPrima  ValoreOggi read(ValoreOggi)

PROCEDURE ContaGiorni(NumeroGiorniTotale:integer; VAR GiorniInSalita, PROCEDURE ContaGiorni(NumeroGiorniTotale:integer; VAR GiorniInSalita, GiorniInDiscesa :integer); {in: NumeroGiorniTotale out: GiorniInSalita, GiorniInDiscesa } VAR Giorno: integer; ValoreOggi, GiornoPrima: real; BEGIN Giorno := 1; GiorniInSalita:=0; GiorniInDiscesa:=0; read(ValoreOggi); WHILE Giorno <> NumeroGiorniTotale DO Giorno := Giorno + 1; GiornoPrima := ValoreOggi; read(Oggi); IF ValoreOggi < GiornoPrima THEN GiorniInDiscesa= GiorniInDiscesa+1 ELSE IF ValoreOggi > GiornoPrima THEN GiorniInSalita= GiorniInSalita+1 END;

Il CICLO FOR FOR := DO FOR I:=1 TO 10 DO FOR I:=100 DOWNTO 20 DO REGOLE SINTATTICHE PER FOR….TO ….. DO FOR Identificatore DO espressione Variabile per il controllo del ciclo Valore iniziale assunto dalla variabile di controllo := istruzioni TO DOWNTO Valore finale assunto dalla variabile di controllo FOR I:=1 TO 10 DO writeln(‘I= ‘,I:5) FOR I:=100 DOWNTO 20 DO writeln(‘I= ‘,I:5)

Somma:=Somma+Contatore; writeln(Contatore:5, Somma:5) END; FOR Contatore:=1 TO 5 DO BEGIN Somma:=Somma+Contatore; writeln(Contatore:5, Somma:5) END; writeln(‘FINE’); Somma:=0; Contatore:=0; WHILE Contatore<>5 DO BEGIN Contatore:=Contatore+1; Somma:=Somma+Contatore; writeln(Contatore:5, Somma:5) END; writeln(‘FINE’); istruzioni no si Eseguo il ciclo?

N.B. Come variabili di controllo si possono usare solo integer e char. Somma:=0; FOR Contatore:=10 DOWNTO 5 DO BEGIN Somma:=Somma+Contatore; writeln(Contatore:3,’-’, Somma:3) END; writeln(‘FINE’); 10- 10 9- 19 8- 27 7- 34 6- 40 5- 45 FINE E’ possibile usare come variabile di controllo anche una variabile char FOR Lettera:= ‘A’ TO ‘Z’ DO write(Lettera); writeln; Lettera:=pred(‘A’); WHILE Lettera <> ‘Z’ DO BEGIN Lettera:=succ(Lettera); write(Lettera) END; writeln; ABCDEFGHIJKLMNOPQRSTUVWXYZ N.B. Come variabili di controllo si possono usare solo integer e char.

{per eseguire N volte delle istruzioni} FOR Conta  1 TO N DO Se il numero di passi da eseguire in un ciclo è noto a priori allora si preferisce usare il FOR al posto del WHILE. {per eseguire N volte delle istruzioni} FOR Conta  1 TO N DO istruzioni {per eseguire K istruzioni non ripetitive e N-K volte istruzioni ripetitive} esegui le prime K istruzioni non ripetitive FOR Conta  K TO N DO istruzioni

Giorno := 1; GiorniInSalita:=0; GiorniInDiscesa:=0; read(ValoreOggi); WHILE Giorno <> NumeroGiorniTotale DO BEGIN Giorno := Giorno + 1; GiornoPrima := ValoreOggi; ………... END; Giorno := 1; GiorniInSalita:=0; GiorniInDiscesa:=0; read(ValoreOggi); FOR Giorno:=2 TO NumeroGiorniTotale DO BEGIN GiornoPrima := ValoreOggi; ……………... END;

CORREZIONE ESERCIZIO SU ORDINAMENTO AREE

UN PO’ DI STORIA “Liber Abaci” Intorno all’anno 1170 a Pisa un commerciante di nome Bonaccio Pisano ebbe un figlio che chiamò Leonardo. Per motivi di lavoro si trasferì presto a Algeri dove Leonardo crebbe, studiò e imparò l’arabo avendo dei precettori musulmani. Da costoro imparò la matematica indo-arabica, il sistema decimale con la notazione posizionale delle cifre e l’uso dello zero. Leonardo Pisano scrisse il primo libro di matematica occidentale il “Liber Abaci” introducendo le cifre arabe Affascinato dal mondo e dalla cultura araba dove ogni persona ha nel suo cognome anche il nome del padre aggiunse al suo nome di Leonardo il cognome Filius Bonacci trasformato per brevità in Fibonacci.

Problema Nel 1228 messer Leonardo Pisano detto Fibonacci si pose il seguente problema: posta una coppia di conigli in un recinto supponiamo che questa coppia dopo due mesi generi un’altra coppia e successivamente ne generi una al mese. La seconda coppia a sua volta dopo altri due mesi ne genera un’altra e così via . Dopo un anno, cioè dopo 12 mesi quante coppie di conigli ci saranno nel recinto?

I numeri di Fibonacci 1 1 2 2 3 3 5 4 8 5 13

ALCUNI CASI STRANI

I numeri di Fibonacci I primi due numeri valgono 0 e 1. Tutti gli altri numeri sono ciascuno uguale alla somma dei due numeri che lo precedono. 0 1 1 1 1 2 1 2 3 2 3 5 3 5 8 5 8 13 ………………………... Si vogliono generare i primi 20 numeri di Fibonacci e mostrarli sette per riga. 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 Pseudo codice Inizializza le variabili(Precedente, Attuale, N) Genera e mostra numeri di Fibonacci(Precedente, Attuale, N)

Inizializza le variabili Genera e mostra N numeri di Fibonacci NuovoNumero

PROGRAM Fibonacci1(input,output); PROCEDURE NuovoNumero(VAR Prec, Att: integer); VAR Temp:integer; BEGIN Temp:=Prec+Att; Prec:=Att; Att:=Temp END; PROGRAM Fibonacci1(input,output); {Mostra i primi N numeri di Fibonacci assegnato N} CONST SpazioPerNumero=8; VAR Precedente, Attuale, N: integer; PROCEDURE Inizializza(VAR Primo, Secondo, N1: real); BEGIN ………….. END; PROCEDURE NuovoNumero(VAR Prec, Att: real); BEGIN………….. END; PROCEDURE GeneraMostraFibonacci(P,A:real;N1:integer); VAR Conta:integer; BEGIN writeln('F',P :1:0, P : SpazioPerNumero:0); writeln('F',A :1:0, A : SpazioPerNumero:0); FOR Conta:=2 TO N1 DO NuovoNumero(P, A); writeln('F',Conta:1, A : SpazioPerNumero:0); END; PROCEDURE Inizializza(VAR Zero, Uno: real; VAR N1:integer); BEGIN Zero:=0; Uno:=1; write(' Dammi il numero di Fibonacci richiesto '); readln(N1) END; {***************** MAIN ****************} BEGIN Inizializza(Precedente, Attuale, N); GeneraMostraFibonacci(Precedente, Attuale, N); END. (Fibon1)

ESERCIZIO N.8 Detto Fn l’ennesimo numero di Fibonacci scrivere un programma che calcoli l’espressione: A=Fn+1* Fn-1 - F2n Mostrare i valori di A per N=1,2,3,4,5,6,7,8,9,10

IF Numero > PiuAlto THEN PiuAlto :=Numero END; readln; Problema Inserire N numeri e mostrare a video il numero più alto inserito fino a quel momento. Pseudo codice readln(N) readln(Numero) PiuAlto  Numero IF Numero > PiuAlto THEN FOR Conta:=2 TO N DO BEGIN read(Numero); IF Numero > PiuAlto THEN PiuAlto :=Numero END; readln;

Generalizzando {algoritmo per la ricerca dell’evento più significativo} introduci il primo evento PiuSignificativo  Evento WHILE ci sono altri eventi DO introduci Evento IF Evento è più significativo di PiuSignificativo THEN

Le istruzioni vengono sicuramente eseguite almeno una volta. Il CICLO REPEAT ….. UNTIL REGOLE SINTATTICHE PER REPEAT ….. UNTIL Se l’espressione è vera allora si esce REPEAT …. UNTIL espressione booleana UNTIL REPEAT istruzioni Le istruzioni vengono sicuramente eseguite almeno una volta. write(‘Introduci un numero positivo: ‘); readln(Numero) WHILE Numero<=0 DO END; REPEAT write(‘Introduci un numero positivo: ‘); readln(Numero) UNTIL Numero >0

Nel caso del REPEAT si esce quando l’espressione diventa vera. La differenza tra WHILE e REPEAT consiste principalmente nel fatto che le espressioni booleane di controllo sono tra loro complementari. Nel caso del WHILE si esce quando l’espressione diventa falsa; Nel caso del REPEAT si esce quando l’espressione diventa vera. istruzioni no si Eseguo il ciclo? istruzioni no Eseguo il ciclo? si REPEAT WHILE

DIFFERENZE TRA FOR - REPEAT - WHILE Le condizioni di entrata e uscita dal FOR sono stabilite prima di entrare nel ciclo. La variabile di controllo del ciclo è aumentata o diminuita automaticamente. Questa variabile può essere usate all’interno del ciclo ma non modificata. La sequenza del REPEAT è eseguita almeno una volta sempre. L’espressione booleana di controllo è eseguita dopo le istruzioni interne al ciclo. Quando l’espressione diventa vera allora si esce dal ciclo. Nel caso del WHILE l’espressione di controllo è valutata prima di entrare nel ciclo. Se essa è vera allora si esegue il ciclo. Si esce dal ciclo quando l’espressione diventa falsa e quindi in questo caso non si eseguono le istruzioni del ciclo.

Come decidere tra FOR - REPEAT - WHILE Se sono noti i valori della variabile di controllo di inizio e fine ciclo, e questi non devono essere cambiati nel ciclo e la variabile deve essere incrementata o diminuita di 1, allora si usa FOR. Se il FOR non è applicabile e le istruzioni del ciclo devono essere eseguite almeno una volta allora usa REPEAT. Se né il FOR né il REPEAT è utilizzabile allora ricorri al WHILE. In caso di indecisione si usa il WHILE.

ESEMPIO Problema Il signor Esposito vuole fare un viaggio con la moglie e sua figlia. Durante il viaggio si fermerà per fare benzina, per mangiare e per alloggiare. Quando alloggia allora mangia anche. Esposito vuole spendere solo 150.000 al giorno per l’alloggio per tutta la famiglia. Se il prezzo della camera del motel è troppo alto allora lui cambia motel. Supponiamo che Esposito parta e ad ogni tappa aggiorni i suoi conti. Alla fine del viaggio si vuole sapere la spesa totale.

Esempio di Input/Output Spese di viaggio Per caricare le spese di viaggio digitare: A per spese alloggio B per spese benzina C per spese cibo U per uscire Quanti soldi puoi spendere ? 560000 Sono pronto: B Prezzo benzina: 50000 Sono pronto: A Prezzo per camera: 160000 Grazie ma e' troppo per noi Nuovo Motel. Prezzo per camera: 150000 Perfetto! Si dorme qui. Conto per la persona n. 1 : 52000 Conto per la persona n. 2 : 42000 Conto per la persona n. 3 : 15000 Totale conto pranzo : Lit. 109000.00

Sono pronto: C Conto per la persona n. 1 : 56000 Conto per la persona n. 2 : 54000 Conto per la persona n. 3 : 23000 Totale conto pranzo : Lit. 133000.00 Sono pronto: U Spese sostenute per la benzina: 50000 Spese sostenute per il cibo: 242000 Spese sostenute per l'alloggio: 150000 Spese sostenute per il viaggio: 442000 BRAVO !!! Hai risparmiato 118000

InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel, Capitale); Pseudo codice Mostra Istruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel, Capitale); IntroduciSpese; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale) RAPPRESENTAZIONE GRAFICA ContoBenzina ContoCibo ContoMotel NumPersone MaxAlloggio Capitale ContoBenzina ContoCibo ContoMotel Capitale ContoBenzina ContoCibo ContoMotel Capitale ContoBenzina ContoCibo ContoMotel Capitale Mostra Istruzioni Introduci Spese A B C U Risultati Finali ContoCibo ContoBenzina ContoCibo ContoMotel Capitale ContoCibo ContoMotel Inizializza variabili ContoBenzina Alloggiare Benzina Cibo Esci

{********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END.

PROGRAM SpeseViaggio(input,output); {Gestione delle spese di viaggio relative a benzina, mangiare, dormire} CONST NumPersone=3; MaxAlloggio=150000; VAR ContoBenzina, ContoCibo, ContoMotel,Capitale: real; TipoSpesa: char; PROCEDURE MostraIstruzioni; BEGIN writeln('Spese di viaggio'); writeln(' Per caricare le spese di viaggio digitare: '); writeln(' A per spese alloggio'); writeln(' B per spese benzina'); writeln(' C per spese cibo'); writeln(' U per uscire'); END; {********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END.

{Inizializza i valori delle variabili} BEGIN PROCEDURE InizializzaVariabili(VAR ContoBenzina, ContoCibo, ContoMotel,Capitale:real); {Inizializza i valori delle variabili} BEGIN ContoBenzina:=0; ContoCibo :=0; ContoMotel :=0; writeln('Quanti soldi puoi spendere ? '); readln(Capitale) END; PROCEDURE Benzina(VAR ContoBenzina:real); {in: totale spese benzina escluse quelle attuali out: totale spese benzina incluse quelle attuali} VAR Costo:real; {spesa per la benzina a questo passo} write('Prezzo benzina: ');readln(Costo); ContoBenzina:= ContoBenzina+Costo; {********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END.

PROCEDURE Mangiare(VAR ContoCibo:real); {in: totale spese pranzi escluse quelle attuali out: totale spese pranzo incluse quelle attuali} VAR Conto, {spesa per il pranzo a persona} TotaleConto:real; {spesa per il pranzo a questo passo} Persona :integer; {persona per la quale si fa la spesa per il pranzo} BEGIN TotaleConto:=0; FOR Persona:=1 TO NumPersone DO write('Conto per la persona n. ',Persona:1,' : '); readln(Conto); TotaleConto:= TotaleConto+Conto; END; write('Totale conto pranzo : Lit. ', TotaleConto:4:2); ContoCibo := ContoCibo + TotaleConto; {********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END.

PROCEDURE Alloggiare(VAR ContoMotel, ContoCibo :real); {in: totale spese alloggio escluse quelle attuali out: totale spese alloggio incluse quelle attuali} VAR CostoPerAlloggio:real; {costo per camera} BEGIN write('Prezzo per camera: '); readln(CostoPerAlloggio); WHILE CostoPerAlloggio > MaxAlloggio DO writeln('Grazie ma e'' troppo per noi'); write('Nuovo Motel. Prezzo per camera: '); readln(CostoPerAlloggio); END; writeln('Perfetto! Si dorme qui.'); ContoMotel:= ContoMotel+ CostoPerAlloggio ; Mangiare(ContoCibo) {********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END.

{in: totale spese parziali out: totale spese viaggio} VAR PROCEDURE RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel,Capitale:real); {in: totale spese parziali out: totale spese viaggio} VAR Totale:real; {costo per camera} BEGIN writeln('Spese sostenute per la benzina: ', ContoBenzina:8:0); writeln('Spese sostenute per il cibo: ', ContoCibo:8:0); writeln('Spese sostenute per l''alloggio: ', ContoMotel:8:0); writeln('Spese sostenute per il viaggio: ', (ContoBenzina+ ContoCibo +ContoMotel):8:0); Totale:=(ContoBenzina+ ContoCibo +ContoMotel); IF Totale < Capitale THEN writeln('BRAVO !!! Hai risparmiato ',(Capitale-Totale):8:0) ELSE writeln(' Hai fatto debiti per ',(Totale - Capitale):8:0); END; {********** MAIN ***********} BEGIN MostraIstruzioni; InizializzaVariabili(ContoBenzina, ContoCibo, ContoMotel,Capitale); REPEAT WRITELN; write('Sono pronto: '); readln(TipoSpesa); CASE TipoSpesa OF 'A': Alloggiare(ContoMotel, ContoCibo); 'B': Benzina(ContoBenzina); 'C': Mangiare(ContoCibo); 'U': END; UNTIL TipoSpesa = 'U'; RisultatiFinali(ContoBenzina, ContoCibo, ContoMotel, Capitale); readln END. (viaggio)

CICLI ANNIDATI Sono cicli annidati quei cicli contenuti in altri cicli più esterni. Quando sono necessari cicli annidati si progettano prima i cicli più esterni e poi quelli più interni.

Scrivere le tabelline dei numeri da 0 a 9 come in figura. ESEMPIO Problema Scrivere le tabelline dei numeri da 0 a 9 come in figura. * 0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 1 0 1 2 3 4 5 6 7 8 9 2 0 2 4 6 8 10 12 14 16 18 3 0 3 6 9 12 15 18 21 24 27 4 0 4 8 12 16 20 24 28 32 36 5 0 5 10 15 20 25 30 35 40 45 6 0 6 12 18 24 30 36 42 48 54 7 0 7 14 21 28 35 42 49 56 63 8 0 8 16 24 32 40 48 56 64 72 9 0 9 18 27 36 45 54 63 72 81 Output

Pseudo codice mostra ‘*’ FOR Moltiplicatore  0 TO 9 DO mostra Moltiplicatore writeln FOR Moltiplicando  0 TO 9 DO mostra Moltiplicando mostra il prodotto su una linea mostra il prodotto su una linea FOR Moltiplicatore  0 TO 9 DO mostra Moltiplicatore * Moltiplicando

PROGRAM Tabelline(output); {Mostre le tabelline tra 0 e 9} CONST Spazi=4; VAR Moltiplicando, Moltiplicatore: integer; BEGIN write(‘*’); FOR Moltiplicatore:=0 TO 9 DO write(Moltiplicatore:Spazi); writeln; FOR Moltiplicando :=0 TO 9 DO write(Moltiplicando :1); write(Moltiplicando * Moltiplicatore:Spazi); END END.

I cicli annidati possono anche avere le variabili di controllo dipendenti dalle variabili dei cicli esterni. Supponiamo di voler stampare una serie di asterischi come in figura. * ** *** **** ***** Supponiamo di voler assegnare dall’esterno il numero di asterischi della riga finale. Pseudo codice Introduci NumeroAsterischi desiderato FOR Riga  1 TO NumeroAsterischi mostra una linea di asterischi mostra una linea di asterischi FOR Asterisco  1 TO Riga DO mostra un asterisco;

PROGRAM Asterisco(input,output); CONST Stella=‘*’; VAR NumeroAsterischi, Riga, Asterisco: integer; BEGIN write(‘Quanti asterischi vuoi sull’ultima riga: ‘); readln(NumeroAsterischi); FOR Riga:=1 TO NumeroAsterischi DO FOR Asterisco:=1 TO Riga DO write(Stella); writeln END END;

Esercizio Stampare un albero di asterischi come in figura sapendo che deve essere formato da N linee più due di tronco e una linea di base. * *** **** ***** ******

SUGGERIMENTI PER TESTARE I PROGRAMMI Quando bisogna fare manutenzione a procedure proprie o di altri bisogna fare attenzione ad una serie di possibili errori non rilevati dal compilatore.

Non far mai seguire a DO un ; sia con WHILE che con FOR Esempio procedura Viaggio. Se poniamo PROCEDURE Alloggiare(VAR ContoMotel, ContoCibo :real); {in: totale spese alloggio escluse quelle attuali out: totale spese alloggio incluse quelle attuali} VAR CostoPerAlloggio:real; {costo per camera} BEGIN write('Prezzo per camera: '); readln(CostoPerAlloggio); WHILE CostoPerAlloggio > MaxAlloggio DO; writeln('Grazie ma e'' troppo per noi'); write('Nuovo Motel. Prezzo per camera: '); readln(CostoPerAlloggio); END; writeln('Perfetto! Si dorme qui.'); ContoMotel:= ContoMotel+ CostoPerAlloggio ; Mangiare(ContoCibo)

Per caricare le spese di viaggio digitare: A per spese alloggio B per spese benzina C per spese cibo U per uscire Quanti soldi puoi spendere ? 500000 Sono pronto: A Prezzo per camera: 45000 Grazie ma e' troppo per noi Nuovo Motel. Prezzo per camera: 500000 Perfetto! Si dorme qui. Conto per la persona n. 1 : 50000 Conto per la persona n. 2 : 45000 Conto per la persona n. 3 : 12000 Totale conto pranzo : Lit. 107000.00 Sono pronto: U Spese sostenute per la benzina: 0 Spese sostenute per il cibo benzina: 107000 Spese sostenute per l'alloggio: 500000 Spese sostenute per il viaggio: 607000 Hai fatto debiti per 107000

Usare sempre BEGIN … END per delimitare blocchi di istruzioni PROCEDURE Mangiare(VAR ContoCibo:real); {in: totale spese pranzi escluse quelle attuali out: totale spese pranzo incluse quelle attuali} VAR Conto, {spesa per il pranzo a persona} TotaleConto:real; {spesa per il pranzo a questo passo} Persona :integer; {persona per la quale si fa la spesa per il pranzo} BEGIN TotaleConto:=0; FOR Persona:=1 TO NumPersone DO {BEGIN} write('Conto per la persona n. ',Persona:1,' : '); readln(Conto); TotaleConto:= TotaleConto+Conto; {END; } write('Totale conto pranzo : Lit. ', TotaleConto:4:2); ContoCibo := ContoCibo + TotaleConto; END; Quanti soldi puoi spendere ? 500000 Sono pronto: C Conto per la persona n. 1 : Conto per la persona n. 2 : Conto per la persona n. 3 : 10000 Totale conto pranzo : Lit. 10000.00 Sono pronto: A Prezzo per camera: 45000

Il WHILE viene eseguito all’infinito Essere sicuri che la condizione di uscita di un WHILE o REPEAT si verifichi sempre. Cosa mostra il video con questo programma? Somma:=0; read(Numero); WHILE Numero > 0 DO writeln(Somma:10); Somma:=Somma + Numero; Il WHILE viene eseguito all’infinito Quando in un programma vi sono procedure contenenti cicli è opportuno in fase di test mettere scritte di controllo in ingresso e in uscita alle singole procedure.

Somma prima di uscire anche il numero negativo Uscita dalla procedura mal controllata. Si vuole mostrare la somma dei numeri positivi introdotti. Cosa mostra il video di questo programma? Somma:=0; REPEAT read(Numero); Somma:=Somma + Numero UNTIL Numero <= 0; writeln(Somma:10); Somma prima di uscire anche il numero negativo Si vuole mostrare la somma dei primi 100 numeri interi. Cosa mostra il video di questo programma? Somma:=0; Conta:=1; REPEAT Somma:=Somma + Conta; Conta:=Conta+1; UNTIL Conta=100; writeln(Somma:10); Non somma il numero 100

Posizione errata dell’istruzione Cosa mostra il video di questo programma? Somma:=0; FOR Conta:=1 TO 100 DO BEGIN IF Conta MOD 5 =0 THEN writeln(‘La somma dei primi ‘,Conta:1, ‘ e’’ ,Somma :1); Somma:=Somma + Conta; END; Posizione errata dell’istruzione E’ necessario mettere un loop Cosa mostra il video di questo programma? readln(Numero); IF Numero <=0 THEN BEGIN writeln(‘Introduci un numero positivo ‘); END; writeln(‘Numero= ‘,Numero:1)

Consigli per testare i cicli. Testare il ciclo innanzitutto con un piccolo insieme di dati. Quindi non fare un ciclo di 100 o più passi ma solo di pochi passi e quindi fare il test. Gli errori mostrati prima emergono più facilmente. Testare il ciclo relativamente ai valori di entrata/uscita. Verificare cioè che le condizioni di entrata/uscita previste siano rispettate. Testare il corpo del ciclo con valori sicuramente sbagliati. Testare il corpo del ciclo con valori sicuramente corretti. Testare il corpo del ciclo anche forzando con asserzioni alcuni valori.

Esercizi dal libro pag. 259 n. 22, 25 pag. 260 n. 28 pag. 261 n. 32

FINE CAP. 6