Corso di Informatica B/C 2014-‐15 1-‐1
Esercizi di MATLAB per il corso di Informatica B/C
2014/2015
Chapter 1 Introduzione ............................................................................................................................. 1-‐2
Chapter 2 Funzioni .................................................................................................................................. 2-‐20
Chapter 3 Ricorsione ............................................................................................................................... 3-‐42
Chapter 4 Accesso ai file .......................................................................................................................... 4-‐62
Chapter 5 Diagrammi .............................................................................................................................. 5-‐63
Corso di Informatica B/C 2014-‐15 1-‐2
Chapter 1 Introduzione
1. Scrivere un programma che data una matrice a NxN crea una nuova matrice b ruotata di 90 gradi in senso antiorario rispetto ad a. Si consideri N=4 e la matrice a inizializzata con i valori
[1 2 3 4; 2 3 4 5; 6 7 8 9; 0 0 0 0]
Soluzione -‐ script
N=4; a = [1 2 3 4; 2 3 4 5; 6 7 8 9; 0 0 0 0]; for x=1:N for y=1:N b(N+1-y,x)=a(x,y); end end %stampo la matrice originale a %stampo la matrice ruotata b
Soluzione -‐ script
N=4; a=[1 2 3 4; 2 3 4 5; 6 7 8 9; 0 0 0 0]; %utilizzo la funzione di MATLAB rot90 a b=rot90(a)
Corso di Informatica B/C 2014-‐15 1-‐3
2. Si realizzi uno script in Matlab che richieda l’inserimento dei tre coefficienti di un’equazione di secondo grado:
e stampi il valore delle radici reali.
Suggerimento
Le radici di un’equazione di secondo grado possono essere calcolate mediante la seguente formula:
Soluzione -‐ script
% Per risolvere l'esercizio bisogna calcolare il discriminante %dell'equazione con la formula b^2-4*a*c Se è positive abbiamo due %radici distinte, %Se è nullo le radici sono reali e coincidenti, %Se è negative le radici non sono reali. a = input('Inserire a: '); b = input('Inserire b: '); c = input('Inserire c: '); delta = b^2-4*a*c; if delta < 0 disp('L''equazione non ha soluzioni reali'); elseif delta==0 disp(['x=' num2str(-b/(2*a))]); else disp(['x1=' num2str((-b-sqrt(delta))/(2*a)) ' x2=' ... num2str((-b+sqrt(delta))/(2*a))]); end
ax
2 + bx+ c = 0
r =�b±
pb2 � 4ac
2
Corso di Informatica B/C 2014-‐15 1-‐4
3. Realizzare uno script che, data una matrice quadrata,
a. ne estragga la diagonale principale. b. ne estragga la diagonale secondaria.
c. elimini la diagonale principale e la secondaria
Soluzione
a)
-‐primo modo usare la matrice logica con true sulla diagonale principale; possiamo costruire una matrice logica B = logical(eye(N)) dove N è la dimensione della matrice di cui vogliamo estrarre la diagonale
A(logical(eye(N))) -‐secondo modo utilizzando la funzione diag :)
diag(A)
b)
-‐primo metodo, utilizzando logical e rot90
A(logical(rot90(eye(N))))
-‐secondo metodo, utilizzando diag e rot90
diag(rot90(A))
c)
-‐primo metodo, usando logical e eye
A(logical(eye(N))) = 0 % elimino la diagonale principale A(logical(rot90(eye(N)))) = 0 % elimino la diagonale secondaria
-‐ secondo metodo usando diag
A -‐ diag(diag(A)) %elimino la diagonale principale A -‐ fliplr(diag(diag(rot90(A)))) %elimino la diagonale secondaria
Corso di Informatica B/C 2014-‐15 1-‐5
4. Scrivere uno script che chieda un anno all’utente e stampi a video se l’anno è bisestile. Il programma deve continuare a chiedere all’utente anni, finché gli anni inseriti sono bisestili. Stampare a video il numero totale di anni bisestili inseriti.
Soluzione
bisestili.m -‐ script
clear clc bisestile = 1; counter = 0; while(bisestile)
n = input(['inserire anno ']); div_4 = (mod(n , 4) == 0); div_100 = (mod(n , 100) == 0); div_400 = (mod(n , 400) == 0); bisestile = ((div_4) && ~(div_100)) || (div_400); stringa_output = num2str(n); if(bisestile == 0)
stringa_output = [stringa_output , ' NON e'' ']; else
stringa_output = [stringa_output ,' e'' ']; counter = counter + 1;
end stringa_output = [stringa_output , 'bisestile']; disp(stringa_output);
end disp(['game over hai inserito esattamente ' , num2str(counter) , ' bisestili'])
Corso di Informatica B/C 2014-‐15 1-‐6
5. Scrivere uno script che analizzi i voti del primo compitino degli anni precedenti, stampando a schermo:
• media dei voti • la media dei voti sufficienti • la varianza dei voti sufficienti • il numero di promossi al primo compitino
% A.A. 2012-‐-‐2013 voti = [2 8 4 8.1 9.25 11.25 4.75 17 6.25 13 10 2 3.25 3.75... 8.5 16 8 1 2.5 12 10.75 6 12 10 11.75 3.5 10.5 8.5 14.25... 16.5 10.75 8 12 1 10 13 6.75 5.75 9.5 12.75 11 8.5 10.25... 14.5 4.25 5.5 9.75 16.5 13 15 13 13.75 13.5];
Soluzione
media.m -‐ script
clear clc % A.A. 2012-‐-‐2013 voti=[2 8 4 8.1 9.25 11.25 4.75 17 6.25 13 10 2 3.25 3.75 8.5 16 8 1 2.5 12 10.75 6 12 10 11.75 3.5 10.5 8.5 14.25 16.5 10.75 8 12 1 10 13 6.75 5.75 9.5 12.75 11 8.5 10.25 14.5 4.25 5.5 9.75 16.5 13 15 13 13.75 13.5]; % calcolo media: soluzione "alla C" count = 0; tot =0; for ii = voti
tot=tot + ii; count = count + 1;
end media = tot/count; % oppure % soluzione alla MATLAB media = mean(voti); disp(['media: ' , num2str(media)]); % calcolo media sufficienti: soluzione "alla C" count = 0; tot = 0; for ii = voti(voti >= 8)
tot=tot + ii; count = count + 1;
end media_suff = tot/count;
Corso di Informatica B/C 2014-‐15 1-‐7
% oppure % soluzione alla MATLAB media_suff = mean(voti(voti >= 8)) disp(['media dei sufficienti: ' , num2str(media_suff)]); % calcolo della varianza dei voti sufficienti "alla C" count = 0; tot = 0; for ii = voti(voti >= 8)
tot = tot + (ii -‐ media_suff).^2; count = count + 1;
end var_suff = tot/count; % oppure soluzione alla MATLAB var_suff = var(voti(voti >= 8)) disp(['varianza dei sufficienti: ' , num2str(var_suff)]); % numero di voti sufficienti: soluzione "alla C" n_suff = 0; for ii = (voti >= 18)
n_suff = n_suff + ii ; end % oppure % numero di voti sufficienti: soluzione "alla MATLAB" n_suff = sum(voti >= 18); disp(['numero di voti sufficienti: ' , num2str(n_suff)]);
6. Scrivere uno script che legga una frase in ingresso e la converta in alfabeto farfallino. Nota: nell’alfabeto farfallino ogni vocale viene sostituita dalla stringa 'vocale+f+vocale', cioè: 'a' = 'afa', 'e' = 'efe', 'i' = 'ifi', 'o' = 'ofo', 'u' = 'ufu'
Soluzione
farfallino.m -‐ script
clear clc frase = input(['inserire una stringa '] , 's'); far = []; for c = frase
far=[far,c]; if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')
far = [far ,'f' ,c]; end
end disp([frase , ' in alfabeto far diventa ' , far])
Corso di Informatica B/C 2014-‐15 1-‐8
7. Scrivere un programma (script) che calcoli la sequenza di Fibonacci di lunghezza 20, poi richieda di inserire un numero 2 < n < 4180 e valuti se il numero è di Fibonacci. Altrimenti restituisce il numero di Fibonacci più vicino. La successione di Fibonacci è definita così:
F(0) = 0 F(1) = 1 F(n) = F (n − 1) + F (n − 2), n > 1
Cioè è composta dai numeri: 0 1 1 2 3 5 8 13 21 34 ...
Soluzione
fibonacci.m -‐ script
clear; clc; fibo = zeros(1,20); fibo(1) = 0; fibo(2) = 1; for i = 3:20
fibo(i) = fibo(i-‐1) + fibo(i-‐2); end fibo a = input('Inserire un numero: '); if sum(a == fibo) > 0
disp([num2str(a) 'e'' un numero di Fibonacci']); else
inferiori = fibo(fibo < a); inferiori = inferiori(end); superiori = fibo(fibo > a); superiori = superiori(1); if superiori -‐ a < a -‐ inferiori
vicino = superiori; else
vicino = inferiori; end disp(['Il numero didi Fibonacci piu'' vicino a ' num2str(a) ' e'' ' num2str(vicino)]);
end
Corso di Informatica B/C 2014-‐15 1-‐9
8. Realizzare uno script che chieda all’utente due parole e stampi a video se una è anagramma dell’altra.
Soluzione
anagramma.m -‐ script
clear clc parola1 = input('Inserire la prima parola: ','s'); parola2 = input('Inserire la seconda parola: ','s'); isto1 = zeros(1,256); isto2 = zeros(1,256); for ii = parola1
isto1(ii) = isto1(ii) + 1; end for ii = parola2
isto2(ii) = isto2(ii) + 1; end if sum(isto1 == isto2) == 256
disp('Le due parole sono una l''anagramma dell''altra'); else
disp('Le due parole non sono anagamma una dell''altra'); end
9. Utilizzando il fatto che il quadrato di n è uguale alla somma dei primi n numeri dispari, creare uno script che calcoli il quadrato di un numero inserito da utente (n < 100).
Soluzione -‐script
clc clear N = input('Inserire il numero da elevare al quadrato (< 100): ' ); numeri = 2 * [0 : N -‐ 1] + 1; c = 1; somma = 0; while c <= N
somma = somma + numeri(c); c = c + 1;
end fprintf('%d^2 = %d\n', N, somma);
Corso di Informatica B/C 2014-‐15 1-‐10
10. Realizzare uno script Matlab per:
a. Creare una matrice M di dimensioni 7 × 5 contenente 0, 1, 2, che rappresenti un momento di una partita di forza 4 in corso.
b. Chiedere ai due giocatori, finchè uno di questi non inserisce la lettera ’q’ (quit), di inserire la colonna (tra 1 e 7) dove intende inserire la propria pedina.
c. Inserire la pedina nella colonna corretta e visualizzare la matrice M così ottenuta.
Soluzione
forza4.m -‐ script
clear clc M = [ 0 0 0 0 0 0 0 ;...
0 0 0 0 0 0 0 ;... 0 0 0 0 0 0 0 ;... 0 0 0 0 0 0 0 ;... 0 0 0 0 0 0 0 ];
turno = 1; a = 6; while (a ~= 'q')
disp(['E'' il turno del giocatore ' num2str(turno)]); a = input('Inserire una giocata (numero di colonna 1-‐7) o uscire (q): '); if a~='q'
if (M(1,a) ~= 0) disp('Giocata illegale');
else indici = M(:,a) == 0; pos_libera = sum(indici); M(pos_libera,a) = turno; imagesc(M); if turno == 1
turno = 2; else
turno = 1; end
end end
end
Corso di Informatica B/C 2014-‐15 1-‐11
11. Verificare se una matrice quadrata di dimensione arbitraria è un quadrato magico. Un quadrato è magico se la somma degli elementi sulle righe, sulle colonne e sulla diagonale principale è la stessa.
Soluzione
clear clc M = magic(4); %M = randi(4,3); [r c] = size(M); assert(r == c); %assert controlla se una condizione è vera. Altrimenti genera un errore somme = zeros(1,2 * r + 1); for ii = 1:r
somme(ii) = sum(M(ii,:)); end for ii = (r+1):2*r
somme(ii) = sum(M(:,ii-‐r)); end somme(2*r+1) = sum(diag(M)); somme if sum(somme == somme(1)) == 2*r+1
disp('La matrice e'' un quadrato magico'); else
disp('La matrice non e'' un quadrato magico'); end
Corso di Informatica B/C 2014-‐15 1-‐12
12. Data una matrice 20 × 20 che rappresenta le partite di un campionato di calcio (con 0 per vittoria in casa, 1 per pareggio 2 per vittoria in trasferta come risultati possibili). Calcolare la classifica finale ordinata.
Soluzione
clear clc squadre = { 'Atalanta' 'Cagliari' 'Cesena' 'Chievo' 'Empoli' ' Fiorentina' 'Genoa'... 'Verona' 'Inter' 'Juventus' 'Lazio' 'Milan' 'Napoli' ' Palermo' 'Parma' 'Roma'... 'Sampdoria' 'Sassuolo' 'Torino' 'Udinese' }; squadre_alt = squadre; risultati = randi(3,20)-1; for ii = 1:20
risultati(ii,ii) = -1; end % Versione facile punti = zeros(20,1); for ii = 1:20
punti(ii) = sum(risultati(ii,:) == 0) * 3 + sum(risultati( ii,:) == 1) + ... sum(risultati(:,ii) == 2) * 3 + sum(risultati(:,ii) == 1);
end %Versione difficile punti_alt = sum(risultati == 0,2) * 3 + sum(risultati == 1,2)+… sum(risultati' == 2,2) * 3 +sum(risultati' == 1,2); %assert controlla se una condizione è vera. Altrimenti genera un errore assert(sum(punti == punti_alt) == 20) %forii=1:20 % disp(['La squadra ' squadre{ii} ' ha totalizzato ' num2str(punti(ii)) ' punti.']); % end %Ordiniamole while (~isempty(punti))
maxi = max(punti); trovato = 0; counter = 1; while trovato == 0
if punti(counter) == maxi disp(['La squadra ' squadre{counter} ' ha totalizzato ' num2str(punti(counter)) ' punti.' ]); punti(counter) = []; squadre(counter) = []; trovato = 1;
else
counter = counter + 1; end
Corso di Informatica B/C 2014-‐15 1-‐13
end end disp('-----------------------------------'); %Oppure chiediamo a MATLAB [punti_alt indici] = sort(punti_alt,'descend'); squadre_alt = squadre_alt(indici); for ii = 1:20
disp(['La squadra ' squadre_alt{ii} ' ha totalizzato ' num2str(punti_alt(ii)) ' punti.']);
end
13. Data una matrice quadrata, leggerla a spirale e metterne il contenuto in un vettore.
La lettura a spirale avviene andando a leggere la prima riga, poi l’ultima colonna, quindi l’ultima riga ed infine la prima colonna. L’operazione si ripete per le colonne e righe progressivamente più interne.
Soluzione
clear clc %creo una matrice d’interi i cui valori sono generati randomicamente M = randi(10,7); M_old = M; riga = 1; colonna = 0; inizio = 1; fine = 0; vec = []; while(~isempty(M)) vec = [vec M(1,:)]; M(1,:) = []; if (~isempty(M)) vec = [vec M(:,end)']; M(:,end) = []; end if (~isempty(M)) vec = [vec M(end,end:-1:1)]; M(end,:) = []; end if (~isempty(M)) vec = [vec M(end:-1:1,1)']; M(:,1) = [];
Corso di Informatica B/C 2014-‐15 1-‐14
end end %genero un errore se qualcosa non e’ andata bene assert(sum(vec) == sum(M_old(:)));
14. (TdE) Dopo una gara automobilistica si ha come risultato tre tabelle le cui colonne rappresentano gli n partecipanti (numerati da 1 a n) e le righe gli m giri di pista effettuati. Il valore di ogni generica cella (i,j) delle tabelle rappresenta il tempo impiegato dal partecipante j per percorrere il giro i.
Si scrivano le istruzioni per:
• calcolare il tempo totale medio che è stato impiegato dai partecipanti per completare la gara;
• determinare il vincitore della gara (cioè il numero del partecipante il cui tempo di percorrenza totale è minore di quello degli altri partecipanti);
• tracciare un grafico in cui l’asse delle x rappresenta i giri compiuti dal vincitore e l’asse delle y il tempo necessario per percorrere i giri.
Soluzione -‐ script
clear clc n_piloti = 10; n_giri = 30; minuti = randi(2,n_piloti,n_giri); secondi = 60 * rand(n_piloti,n_giri); millesimi = 1000 * rand(n_piloti,n_giri); tempo_medio = mean(minuti * 60 + secondi + millesimi / 1000,2); tempo_vinc = min(tempo_medio); vinc = find(tempo_medio == tempo_vinc); disp(['Il vincitore e '' ' num2str(vinc)]); figure(); plot(1:n_piloti,tempo_medio); title('Tempo medio piloti'); xlabel('Numero pilota'); ylabel('Tempo medio');
15. (TdE) Si scriva uno script in Matlab che svolga le seguenti operazioni:
Corso di Informatica B/C 2014-‐15 1-‐15
• Definisce una matrice quadrata di interi di dimensione N*N, con N pari a 5. • Acquisisce da tastiera una sequenza di valori interi che memorizza nella porzione
triangolare superiore della matrice. La parte triangolare superiore della matrice è costituita dalle celle poste sulla diagonale principale e al di sopra di tale diagonale.
• Copia in un array di dimensioni opportune tutti I valori della porzione triangolare di matrice che sono maggiori di -‐10.
• Stampa il contenuto dell’array.
Soluzione
N=5; for x=1:N for y=x:N M(x,y)=input(sprintf('M(%d,%d)= ',x,y)); end end %visualizza M M l=1; for x=1:N for y=x:N if(M(x,y)>-10) a(l)=M(x,y); l=l+1; end end end % oppure a = M(M>-10)' %visualizza a %così a %oppure utilizzando disp disp(a)
16. Scrivere uno script che acquisisce un numero e verifica se è primo o meno stampando un apposito messaggio a video.
Soluzione
n = input('valore: '); d = 2:n/2; mod(n,d) if all(mod(n,d)) %alternativa: ~any(mod(n,d)==0) disp([num2str(n) ' è primo']); else disp([num2str(n) ' non è primo']); end
Corso di Informatica B/C 2014-‐15 1-‐17
17. Si vuole realizzare uno script per analizzare i voti conseguiti da una serie di studenti in un esame, partendo dai punteggi conseguiti in ciascun esercizio. I dati di partenza sono memorizzati in un file, il cui va chiesto il nome all'utente, e sono organizzati nel seguente modo: la prima riga del file contiene i punti massimi per ciascuno degli esercizi dell'esame e le successive righe i punteggi conseguiti da ciascuno degli studenti che ha partecipato all'esame. Un esempio di file è: 5 5 6 4 2 8 1 2 2 2 2 2 5 5 4 4 2 8 5 5 5 3 2 5 5 5 5 1 2 1
dove l'esame era composto da 6 esercizi ed è stato sostenuto da 4 studenti (gli studenti sono identificati con un indice progressivo, es: 1,2,3,4). Lo script deve eseguire le seguenti elaborazioni: • leggere i dati e salvarli in due matrici (una per i punti massimi ed una per i punteggi degli
studenti) • verificare che i punteggi siano consistenti: un punteggio di un esercizio non è consistente
se non compreso tra 0 ed il punteggio massimo conseguibile (per esempio per il primo esercizio dell'esempio sopra il punteggio deve essere compreso tra 0 e 5, estremi inclusi). Un esempio di file inconsistente è il seguente:
5 5 6 4 2 8 7 2 2 2 2 2 5 5 4 4 2 8 5 5 5 3 2 5
SE è stata identificata almeno un'inconsistenza riportare: • il numero di studenti con almeno un punteggio inconsistente • i dati degli studenti che presentano un'inconsistenza (in particolare visualizzare l'indice
dello studente ed i suoi punteggi) ALTRIMENTI eseguire le seguenti elaborazioni: • calcolare i voti • contare il numero di studenti promossi • calcolare i voti massimo e minimo conseguiti dagli studenti promossi • contare il numero di voti scarsi (cioè compresi nell'intervallo [18;21]), di voti mediocri
(voti nell'intervallo [22;25]) e di voti buoni (voti nell'intervallo [26;30]) • cercare e visualizzare gli indici gli studenti che hanno almeno un esercizio insufficiente
(sufficienza al 50% del punteggio massimo) • individuare quale esercizio (o insieme di esercizi) è andato in media peggio (per ciascun
esercizio bisogna calcolare il rapporto tra il punteggio medio conseguito dagli studenti ed il punteggio massimo)
Corso di Informatica B/C 2014-‐15 1-‐18
Soluzione
%caricare punteggi da un file di testo %(prima riga punteggi massimi poi punteggi di ciascuno studente %salvare in due strutture punteggi massimi da punteggi studenti nomefile=input('inserire nome file: ','s'); dati=load(nomefile); punti=dati(1,:); punteggi=dati(2:end,:); [nstudenti nesercizi]=size(punteggi); %controllare se ci sono voti inconsistenti %contare inconsistenze e stampare il seguente report: %numero inconsistenze e lista studenti con dati inconsistenti ninconsistenti=0; inconsistenti=[]; for ii=1:nstudenti if any(punti<punteggi(ii,:) | punteggi(ii,:)<0) ninconsistenti=ninconsistenti+1; inconsistenti(ninconsistenti)=ii; end end disp(['inconsistenti: ' num2str(ninconsistenti)]); if ninconsistenti>0 disp('max punti: '); disp(num2str(punti)); disp('report inconsistenti: '); for ii=1:length(inconsistenti) disp([num2str(inconsistenti(ii)) ': ' num2str(punteggi(ii,:))]); end else %se ok calcolare voti. contare max, min (non bocciato), numero bocciati %e fare statistiche sui presenti... voti=sum(punteggi'); votomax=max(voti); nbocciati=sum(voti<18); votomin=min(voti(voti>=18)); numscarsi=sum(voti>=18 & voti<22); nummedi=sum(voti>=22 & voti<26); numbuoni=sum(voti>=26); disp(['bocciati : ' num2str(nbocciati)]); disp(['max voto : ' num2str(votomax)]); disp(['min voto : ' num2str(votomin)]); disp(['scarsi: ' num2str(numscarsi) ', discreti: ' num2str(nummedi) ', buoni:' num2str(numbuoni) ]); %cercare gli studenti che hanno almeno un esercizio insufficiente %insufficienza: (punteggio<punteggio_massimo/2) nStudEsInsuf=0;
Corso di Informatica B/C 2014-‐15 1-‐19
studEsInsuf=[]; for ii=1:nstudenti if any(punteggi(ii,:)<punti./2) nStudEsInsuf=nStudEsInsuf+1; studEsInsuf(nStudEsInsuf)=ii; end end disp(['studenti con almeno un es insuff: ' num2str(studEsInsuf)]); %vedere quale esercizio è andato in media peggio mediaPunteggi=sum(punteggi)./nstudenti; disp(['max punteggi: ' num2str(punti)]); disp(['media punteggi: ' num2str(mediaPunteggi)]); percPunteggi=mediaPunteggi./punti; percPeggio=min(percPunteggi); numeroEsercizio=1:nesercizi; numEsPeggio=numeroEsercizio(percPunteggi==percPeggio); disp(['esercizio peggiore: ' num2str(numEsPeggio)]); %in alternativa: %disp(['esercizio peggiore: ' num2str(find(percPunteggi==percPeggio))]); end
Corso di Informatica B/C 2014-‐15 2-‐20
Chapter 2 Funzioni
1. Realizzare uno script MATLAB che richieda all’utente l’inserimento due parole e stampi a video se una è anagramma dell’altra.
Soluzione
anagramma.m -‐ script
% Anagramma: versione con funzioni. % leggere 2 parole da tastiera % [parola1, parola2] = leggi_parole(); % costruire gli istogrammi secondo l'alfabeto ASCII esteso (256 simboli) % h1 = calcola_istogramma(parola1); h2 = calcola_istogramma(parola2); % visualizzare gli istogrammi come grafici a barre % figure, bar(h1) figure, bar(h2) % calcolare se si tratta di anagrammi % anagrammi = sono_anagrammi(h1, h2); if (anagrammi) fprintf('Le due parole sono anagrammi\n'); else fprintf('Le due parole NON sono anagrammi\n'); end
leggi_parole.m -‐ funzione
function [p1, p2] = leggi_parole() p1 = input('Inserici una parola o frase: ', 's'); p2 = input('Inserici una parola o frase: ', 's');
Corso di Informatica B/C 2014-‐15 2-‐21
calcola_istogramma.m -‐ funzione
function [h] = calcola_istogramma(parola) h = zeros(1, 256); for c = parola h(c) = h(c) + 1; end
sono_anagrammi.m -‐ funzione
function [an] = sono_anagrammi(h1, h2) % assumo che gli istogrammi abbiano la stessa dimensione % soluzione alla C an = 1; %vero ii = 1; while an && ii < length(h1) an = h1(ii) == h2(ii); ii = ii + 1; end % soluzione alla MATLAB an = all(h1 == h2); % an = ~any(h1 ~= h2);
Corso di Informatica B/C 2014-‐15 2-‐22
2. (TdE) Scrivere un programma che: 1. acquisisca un numero da tastiera e continui a richiedere l'inserimento finché il numero
inserito continui a non essere intero positivo 2. verificare se il numero intero positivo acquisito è perfetto, abbondante o difettivo:
• Perfetto: numero i cui divisori positivi (escluso il numero stesso), sommano al numero stesso.
• Abbondante: numero i cui divisori positivi (escluso il numero stesso), sommano ad un numero maggiore del numero stesso.
• Difettivo: se non è perfetto e non è abbondante. 3. se il numero non è perfetto, controllare se è abbondante o difettivo e stampare un
messaggio a video che lo dica. 4. inoltre, nel caso 3., richiedere anche un altro numero intero positivo b, e controllare se a e
b sono amici: • Amici: due numeri sono amici quando la somma dei divisori del primo (escluso il
numero stesso) coincide al secondo numero; e viceversa. 5. Scrivere un programma che elenchi i primi k numeri abbondanti, con k definito dall'utente.
Soluzione
divisori.m -‐ script
clc clear % inserimento di un numero positivo % a = leggi_intero_positivo(); % a questo punto il numero inserito e` senz'altro positivo % calcolo se il numero e` perfetto, abbondante o difettivo [perfetto, abbondante] = numero_perfetto(a); % se perfetto, allora stampo che e` perfetto e concludo if (perfetto == 1) disp([num2str(a), ' e` perfetto']); else % altrimenti % controllo se e` abbondante o difettivo % if (abbondante == 1) disp([num2str(a), ' e` abbondante']); else disp([num2str(a), ' e` difettivo']); end % acquisisco un altro numero, riusando la funzione b = leggi_intero_positivo(); % a e b sono amici? amici = sono_amici(a, b); if (amici == 1)
Corso di Informatica B/C 2014-‐15 2-‐23
disp([num2str(a), ' e ', num2str(b), ' sono amici']); else disp([num2str(a), ' e ', num2str(b), ' NON sono amici']); end end
leggi_intero_positivo.m -‐ funzione
function [n] = leggi_intero_positivo() n = 0; while n <= 0 n = input('Inserisci un numero intero positivo: '); end
numero_perfetto.m -‐ funzione
function [perfetto, abbondante] = numero_perfetto(n) % calcolo la somma dei divisori (escluso il numero stesso) somma = somma_divisori(n); % calcolo se la somma dei divisori coincide col numero stesso perfetto = (n == somma); % calcolo se il numero e` maggiore della somma dei suoi divisori (abbondante) abbondante = n > somma; % alla fine dell'esecuzione di questa funzione, le variabili 'perfetto' e 'abbondante' saranno disponibili al programma chiamante.
somma_divisori.m -‐ funzione
function somma = somma_divisori(n) % soluzione alla C, non raccomandata somma = 0; for d = 1:n/2 if (~mod(n, d)) % mod(n, d) == 0 somma = somma + d; end end % soluzione alla MATLAB %
Corso di Informatica B/C 2014-‐15 2-‐24
divisori = 1:n/2; resti = mod(n, divisori); divisori_interi = divisori(resti == 0); somma = sum(divisori); % soluzione compatta % somma = sum(divisori(mod(n, divisori) == 0));
sono_amici -‐ funzione
function amici = sono_amici(a, b) amici = (somma_divisori(a) == b) && (somma_divisori(b) == a); % end funzione sono_amici
elenca_k_abbondanti -‐ script
clear; clc; % inserimento di un numero positivo attraverso la chiamata della funzione % k = leggi_intero_positivo(); for i = 1:k [perfetto, abbondante] = numero_perfetto(i); if (abbondante) disp([ num2str(i), ' e'' abbondante']) end end
Corso di Informatica B/C 2014-‐15 2-‐25
3. (TdE) Scrivere una funzione che, ricevendo in ingresso una matrice M di numeri, restituisce in uscita una matrice MR, ottenuta da M nel seguente modo: • si calcola la media aritmetica dei valori di M • per i valori che in M sono minori della media, in MR si pone nella posizione corrispondente
il valore -‐1, • per quelli superiori alla media si pone il valore 1, • per gli altri (quelli uguali alla media) si pone lo stesso valore in M.
Soluzione
transformMatrix.m -‐ funzione
function [MR] = transformMatrix(M) media = mean(mean(M)); MR = M; MR(MR < media) = -1; MR(MR > media) = 1; % fine funzione transformMatrix % soluzione alla C [R, C] = size(M); media = 0; % somma di tutti gli elementi for r = 1:R for c = 1:C media = media + M(r,c); end end % calcolo media media = media / (R * C); % generazione MR elemento per elemento for r = 1:R for c = 1:C if M(r,c) < media MR(r,c) = -1; else if M(r,c) > media MR(r,c) = 1; else MR(r,c) = M(r,c); end end end end
Corso di Informatica B/C 2014-‐15 2-‐26
4. (TdE) Scrivere un programma per la gestione di un magazzino dove ogni prodotto nel magazzino è univocamente identificato da un barcode (un numero intero) e da una tipologia (un carattere). Il software di gestione associa ad ogni prodotto due numeri, il primo che indica il numero di pezzi in stock il secondo che indica il numero di pezzi ordinati. Si ipotizzi che barcode, tipo, stock, ordine siano 4 vettori, già popolati, contenenti tutte le informazioni necessarie per la gestione del magazzino. (l'i-‐simo elemento di stock e di ordine rappresentano le quantità relative al prodotto a cui è associato l'i-‐simo elemento di barcode). Ad esempio: barcodes = [123 ; 1312 ; 12312 ; 1231 ; 99123]; tipo = ['A' ; 'A' ; 'X' ; 'W' ; 'W' ]; stock = [0 ; 300 ; 5 ; 6 ; 0 ]; ordine = [23 ; 100 ; 2 ; 100 ; 0 ]; Si scriva:
a. la funzione “ricerca” che prende in ingresso un barcode e restituisce un messaggio contenente il tipo di prodotto, il numero di pezzi in stock ed in ordine. In caso di multiple occorrenze, scegliere la prima.
b. un esempio di chiamata alla funzione "ricerca". c. la funzione “ricercaMancanti” che, a seconda di un parametro P, restituisca al
programma chiamante un vettore contenente I codici a barre dei prodotti: • (se P = 0) non presenti in stock ma in ordine, • (se P = 1) non presenti in stock che non sono nemmeno in ordine, • (se P = 2) per cui ci sono più pezzi in ordine che attualmente in stock.
d. Scrivere un esempio di chiamata alla funzione ricercaMancanti. e. Si scriva la funzione “aggiungiProdotto”, che permette di aggiungere al magazzino un
nuovo prodotto (barcode + stock + ordine). f. Scrivere un esempio di chiamata alla funzione aggiungiProdotto.
Soluzione
ricerca.m – funzione
% definizione funzioni function [msg] = ricerca (b, t, s, o, bc) bc_indici = find(b == bc); b = b(bc_indici)(1); t = t(bc_indici)(1); s = s(bc_indici)(1); o = o(bc_indici)(1);
Corso di Informatica B/C 2014-‐15 2-‐27
msg = ['il prodotto corrispondente al codice a barre ', num2str(bc), ' e` di tipo ',num2str(t), ' elementi in stock: ', num2str(s),' in ordine: ', num2str(o) ]; end
ricercaMancanti.m -‐ funzione
function [prodotti] = ricercaMancanti(b, t, s, o, P) switch P case 0 bc_indici = find(s == 0 && o > 0); case 1 bc_indici = find(s == 0 && o == 0); case 2 bc_indici = find(o > s); end prodotti = b(bc_indici) end
aggiungiProdotto.m -‐ funzione
function [b, t, s, o] = aggiungiProdotto(b, t, s, o, n_b, n_t ,n_s, n_o) b = [b; n_b]; t = [t; n_t]; s = [s; n_s]; o = [o; n_o]; end
Esempi d’uso delle funzioni
% main barcodes = [123 ; 1312 ; 12312 ; 1231 ; 99123]; tipo = ['A' ; 'A' ; 'X' ; 'W' ; 'W' ]; stock = [0 ; 300 ; 5 ; 6 ; 0 ]; ordine = [23 ; 100 ; 2 ; 100 ; 0 ]; ricerca(barcodes, tipo, stock, ordine, 12312) ricercaMancanti(barcodes, tipo, stock, ordine, 0) ricercaMancanti(barcodes, tipo, stock, ordine, 1) ricercaMancanti(barcodes, tipo, stock, ordine, 2) [barcodes, tipo, stock, ordine] = aggiungiProdotto(barcodes, tipo, stop, ordine, 999, 'F', 3, 24)
Corso di Informatica B/C 2014-‐15 2-‐28
5. Si scriva una funzione che legga una parola e restituisca 1 se tale parola è palindroma, zero altrimenti. Fornire un esempio di chiamata della funzione.
Soluzione
palindroma.m -‐ funzione
function [pal] = palindroma(par) % soluzione "alla C" len = size(par, 2); pal = 1; ii = 1; while((ii <= len / 2 ) && pal) if(par(ii) ~= par(end - ii + 1)) pal = 0; end ii = ii + 1; end % soluzione "alla MATLAB" parAlContrario = par(end : -1 : 1); corrispondenze = (par == parAlContrario); if(sum(corrispondenze == size(par, 2))) pal = 1; else pal = 0; end % alternativa super-compatta pal = sum(par == par(end : -1 : 1))== size(par, 2);
Esempio di chiamata della funzione – script
% acquisisco la parola% parola = input('inserire parola ' , 's'); % chiamo la funzione % pal = palindroma(parola); str = [parola]; if (pal) str = [str , ' è ']; else str = [str , ' NON è ']; end disp([str , ' palindroma']);
Corso di Informatica B/C 2014-‐15 2-‐29
6. (TdE) Una matrice contiene numeri interi. Si vuole progettare una funzione che, ricevendo la matrice e un array di numeri interi che rappresenta una sequenza, cerchi tale sequenza all'interno della matrice. La sequenza cercata può essere disposta, nella matrice, verticalmente dall'alto verso il basso od orizzontalmente, da sinistra verso destra. La funzione deve avere la seguente intestazione:
function [riga, col, dir] = cerca_sequenza(matrice, seq)
se la sequenza è presente nella matrice allora `riga` e `col` indicano gli indici di riga e di colonna del suo primo elemento, mentre `dir` viene posto uguale al carattere 'v' se la sequenza è disposta verticalmente, 'o' se orizzontalmente (se la sequenza è presente ripetuta in più posizioni, i valori restituiti possono essere quelli relativi a una qualsiasi delle ripetizioni); se la sequenza non è presente, `riga` e `col` valgono entrambi 0 e dir vale 'n'.
Per codificare la funzione in questione, si sviluppi prima la seguente funzione ausiliaria
function [pres] = verifica_orizzontale_da_posizione(matrice, seq, riga, col)
che ricerca la sequenza nella matrice a partire da una posizione d’inizio precisa, in direzione orizzontale: riga e col sono il punto di inizio; il risultato [pres] vale 1 se la sequenza è presente, 0 altrimenti.
Successivamente si utilizzi tale funzione per codificare la seguente:
function [riga, col] = cerca_inizio_orizzontale(matrice, seq)
mentre la versione verticale può essere facilmente derivata dalla precedente
function [riga, col] = cerca_inizio_verticale(matrice, seq)
Queste funzioni cercano la sequenza in tutta la matrice con disposizione orizzontale e verticale, restituendo in riga e col le coordinate del punto d’inizio, se la sequenza viene trovata, o il valore 0 altrimenti.
Soluzione
verifica_orizzontale_da_posizione.m -‐ funzione
function [pres] = verifica_orizzontale_da_posizione(matrice, seq, riga, col) len = length(seq); % calcolo la lunghezza della sequenza % estraggo una porzione di matrice a partire da riga,colonna fino a % riga,colonna+len-1 porzione = matrice(riga, col:col+len-1); % se la porzione coincide con la sequenza, la sequenza e` trovata pres = all(porzione == seq);
Corso di Informatica B/C 2014-‐15 2-‐30
cerca_inizio_orizzontale.m -‐ funzione
function [riga, col] = cerca_inizio_orizzontale(matrice, seq) [R, C] = size(matrice); len = length(seq); for r = 1:R % per ogni riga for c = 1:C-len+1 % per ogni colonna (tenendo conto della
% lunghezza della sequenza) % cerca la sequenza orizzontalmente pres = verifica_orizzontale_da_posizione(matrice, seq, r, c); % se trovata, salva riga e colonna, poi ritorna if pres riga = r; col = c; return; end end end
cerca_inizio_verticale.m -‐ funzione
function [riga, col] = cerca_inizio_verticale(matrice, seq) [col, riga] = cerca_inizio_orizzontale(matrice', seq);
cerca_sequenza.m -‐ funzione
function [riga, col, dir] = cerca_sequenza(matrice, seq) % non trovato riga = 0; col = 0; dir = 'n'; % ricerca orizzontale [r, c] = cerca_inizio_orizzontale(matrice, seq); if r ~= 0 riga = r; col = c; dir = 'o'; return; end % ricerca verticale [r, c] = cerca_inizio_verticale(matrice, seq); if r ~= 0 riga = r; col = c; dir = 'v'; return; end
Corso di Informatica B/C 2014-‐15 2-‐31
8. In algebra lineare la matrice compagna di un polinomio di grado N:
è una matrice quadrata NxN avente:
• 1 sulla prima sovra-‐diagonale • i coefficienti, cambiati di segno, sull'ultima riga • 0 (zero) altrove
Scrivere una funzione che, ricevuto in ingresso il vettore dei coefficienti
, restituisca la corrispondente matrice compagna.
Soluzione
matriceCompagna.m – funzione
% function CP = matriceCompagna(coefficienti) % leggo la lunghezza del vettore n = length(coefficienti); % preparo una matrice NxN di zeri CP = zeros(n); % seleziono la sovradiagonale % % leggo la matrice per colonne: % * il primo elemento della sovra-diagonale e` n + 1 % * i successivi elementi sono tutti distanti n + 1 % * mi fermo alla fine della matrice CP(n+1:n+1:end) = 1; %oppure in maniera piu’ compatta CP = diag(ones(n-1,1), 1); % assegno all'ultima riga i coefficienti cambiati di segno CP(n,1:n) = -coefficienti;
c0 + c1x+ c2x2 + · · ·+ cN�1x
N�1
⇥c0 c1 c2 . . . cN�1
⇤
2
66664
0 1 0 · · · 00 0 1 · · · 0· · · · · · · · · · · · · · ·0 0 0 · · · 1
�c0 �c1 �c2 · · · �cN�1
3
77775
Corso di Informatica B/C 2014-‐15 2-‐32
9. Si implementi la funzione “calcolaRischio”, che riceva in ingresso: • un vettore “profiloArgine” che contiene le altezze dell’argine di un fiume, in metri rispetto
al fondo del letto del fiume; in vari punti del corso del fiume a distanze crescenti. • l’altezza attuale del livello dell'acqua del fiume, in metri rispetto al fondo del letto del
fiume. • i millimetri di incremento totale di altezza del fiume dovuti alla pioggia prevista per la
giornata. • Calcoli i punti del profilo a rischio esondazione, cioè quelli per cui:
profiloArgine <= altezzaFiume + (mmIncrementoPrevisto / 1000)
Si realizzi uno script che
a) richiami la funzione calcolaRischio sviluppata al punto precedente; b) visualizzi sullo schermo un grafico che mostri:
• l’andamento del profilo dell’argine • il livello attuale del fiume • i punti dell’argine a rischio di esondazione
c) generi e visualizzi a video una tabella contenente i soli punti dell’argine a rischio di esondazione
• prima colonna: distanza del punto a rischio in metri dalla foce • seconda colonna: altezza dell’argine in quel punto • terza colonna: minuti che passeranno tra il rilevamento e l’esondazione in quel
punto
minuti = (profiloArgine -‐ altezzaFiume) * 1000 / (mmIncrementoPrevisto / 24 * 60)]
Soluzione
calcolaRischio.m – funzione
function rischio = calcolaRischio(profiloArgine, altezzaFiume, mmIncrementoPrevisto) % % input: % profiloArgine: vettore contenente l’altezza dei punti dell’argine % altezzaFiume: scalare contenente il valore dell’altezza attuale del fiume % mmIncrementoPrevisto: scalare contenente il valore dell’incremento di altezza previsto del fiume rischio=find(profiloArgine<=altezzaFiume+(mmIncrementoPrevisto/1000));
argine.m – funzione
Corso di Informatica B/C 2014-‐15 2-‐33
% dati di esempio profiloArgine = [10 10 10 9 8 8 7 10 11 14 20 12 3]; nCampioni = length(profiloArgine); % si supponga che il profilo sia già creato % leggiamo l'altezza altezzaFiume = input('Altezza attuale del fiume in metri: '); % dominio (in metri) x = 1:nCampioni; % costante, altezza del fiume yAltezza = zeros(1, nCampioni); % assegno il valore dell'altezza (supponiamo letto da tastiera) yAltezza(:) = altezzaFiume; % plot del profilo dell'argine plot(x, profiloArgine); hold on % plot dell'atezza (costante) plot(x, yAltezza); % plot dei punti a richio convertendo i mm in metri plot(puntiARischio, altezzaFiume + mmIncrementoPrevisto /1000, '*'); hold off % la tabella avrà [metri, profiloArgine, minuti] % metri metri = x; % minuti minuti = 1000 * 24 * 60 * abs(profiloArgine - altezzaFiume) / (mmIncrementoPrevisto); % creo la tabella tabella = [metri', profiloArgine, minuti]; % seleziono solo i punti a rischio (tutte le colonne) tabella = tabella(puntiARischio, :); % visualizzo disp(tabella);
Corso di Informatica B/C 2014-‐15 2-‐34
10. La logistic map è una sequenza di numeri reali x(0), x(1), x(2), ..., tali che, per ogni numero intero naturale n, si ha che:
x(n+1) =r * x(n) * [1-‐x(n)]
dove 0 < x(0) < 1 e r > 0 è un numero reale.
Per esempio, prendendo x(0) = 0.2 e r = 3.2, i primi quattro numeri della sequenza sono: 0.2000 0.5120 0.7995 0.5129
Scrivere la funzione con la seguente intestazione:
function [x, rip] = logisticMap(x0, r, lun)
che, ricevendo il primo valore x(0) della sequenza, il coefficiente r, e un valore lun rappresentante la possibile lunghezza di sequenza, calcola in successione gli elementi della logistic map, fino a un numero massimo di lun elementi, e li inserisce nel vettore x.
Durante la generazione della sequenza, se prima di raggiungere il numero di elementi lun si ottiene un elemento già generato in precedenza, allora il vettore x viene riempito con gli elementi fino a quello ripetuto (incluso) e il parametro rip viene posto a 1. Se nessun elemento si ripete, il vettore x viene riempito con i primi lun elementi della sequenza, e il parametro rip viene posto a 0.
Per esempio, con la chiamata:
[a b] = logisticMap(0.3, 2, 10)
si ottiene:
a = 0.3000 0.4200 0.4872 0.4997, 0.5000, 0.5000 b = 1
mentre con la chiamata:
[a b] = logisticMap(0.3, 1.3, 8)
si ottiene:
a = 0.3000 0.2730 0.2580 0.2489 0.2430 0.2391 0.2365 0.2348 b = 0
Corso di Informatica B/C 2014-‐15 2-‐35
Soluzione
logisticMap.m – funzione
function [x, rip] = logisticMap(x0, r, lun) x = x0; % continua mentre la lunghezza non e` stata raggiunta while length(x) < lun % l'elemento successivo al corrente e` determinato dalla formula % % con x(length(x)) prendiamo l'ultimo elemento x(n) % ovvero x(end), se preferite x1 = r * x(length(x)) * (1 - x(length(x))); % controllo se gia` generato if any(abs(x-x1) <= 0.0001) % riporto a 1 rip = 1; % inserisco l'elemento % % identico a x = [x, x1]; x(length(x) + 1) = x1; % ritorno immediatamente return; else % inserisco l'elemento % % identico a x = [x, x1]; x(length(x) + 1) = x1; end end % riporto a zero in tutti gli altri casi rip = 0; end
Corso di Informatica B/C 2014-‐15 2-‐36
11. (TdE) Scrivere una funzione che prende come parametro due matrici A e B, delle stesse dimensioni, e restituisce i seguenti 3 valori:
• Il numero totale di elementi uguali in posizioni corrispondenti. • Il numero di elementi di A massimali per la matrice B, cioè il numero di posizioni, nella
matrice A, in cui è presente un numero che è maggiore o uguale a tutti gli elementi presenti nella matrice B.
• Il numero massimo di elementi di A massimali per la matrice B (secondo la definizione precedente) presenti in ogni colonna della matrice A.
Soluzione
massimali.m -‐ funzione
function [r1 r2 r3] = massimali(A, B) % r1 % elementi uguali in posizioni corrispondenti t1 = A == B; r1 = sum(sum(t1)); % r2 % cerchiamo il massimo in B M = max(max(B)); % i numeri di A maggiori di M saranno maggiori (o uguali) a % tutti gli altri elementi di B (in quanto M è il massimo) t2 = A >= M; r2 = sum(sum(t2)); % r3 % somma lungo le righe tutti gli elementi massimali sc = sum(t2); % cerco il massimo r3 = max(sc);
Corso di Informatica B/C 2014-‐15 2-‐37
12. Si richiede di progettare e scrivere una funzione che, dato N un numero intero positivo, senza fare uso di ricorsione e usando al massimo un ciclo (e.g., for, while) costruisca una matrice quadrata di dimensioni N*2 x N*2 con il seguente schema: (esempio per N = 5)
Punto facoltativo, ottenere la seguente matrice:
Soluzione
frame.m – funzione
function [M] = frame(n) n = 2 * n; % raddoppio n M = zeros(n); % parto da una matrice di soli zeri" for ii = 1:n % per ogni sottomatrice "centrata M(ii:n-ii+1, ii:n-ii+1) = M(ii:n-ii+1, ii:n-ii+1) + 1; % alternativamente M(ii:n-ii+1, ii:n-ii+1) = ii; e non serve inizializzare a zeros(); % punto facoltativo, ritocco gli angoli M([ii, n-ii+1], [ii, n-ii+1]) = -1; end
2
666666666666664
1 1 1 1 1 1 1 1 1 11 2 2 2 2 2 2 2 2 11 2 3 3 3 3 3 3 2 11 2 3 4 4 4 4 3 2 11 2 3 4 5 5 4 3 2 11 2 3 4 5 5 4 3 2 11 2 3 4 4 4 4 3 2 11 2 3 3 3 3 3 3 2 11 2 2 2 2 2 2 2 2 11 1 1 1 1 1 1 1 1 1
3
777777777777775
2
666666666666664
�1 1 1 1 1 1 1 1 1 �11 �1 2 2 2 2 2 2 �1 11 2 �1 3 3 3 3 �1 2 11 2 3 �1 4 4 �1 3 2 11 2 3 4 �1 �1 4 3 2 11 2 3 4 �1 �1 4 3 2 11 2 3 �1 4 4 �1 3 2 11 2 �1 3 3 3 3 �1 2 11 �1 2 2 2 2 2 2 �1 1�1 1 1 1 1 1 1 1 1 �1
3
777777777777775
Corso di Informatica B/C 2014-‐15 2-‐38
13. Il sig. Rossi ha ottenuto un finanziamento di 100000 euro. Ha scelto una formula con tasso fisso al 5%, quindi ogni mese, per N anni, dovrà pagare una rata mensile. La rata mensile è composta di una quota capitale più una quota d’interessi. La quota capitale è fissata in modo tale che la somma di tutte le quote capitali dia l'ammontare finanziato, mentre gli interessi sono calcolati in base al residuo del mese precedente. Al primo mese il residuo è il totale finanziato. Il tasso dato è annuo e va diviso per il numero di mesi. Implementare la seguente funzione (formula ammortamento all'italiana):
[rata residuo interessi] = calcola_amm(finanziamento, tasso, anni)
che calcola il piano di ammortamento su un numero di anni indicato come parametro (ad esempio, anni = 3).
Se ad esempio il finanziato è pari a 500 euro, con un tasso annuo del 12% si ottiene in 1 anno: Rata Residuo Interessi -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐ 46.66667 458.33333 5.00000 46.25000 416.66667 4.58333 45.83333 375.00000 4.16667 45.41667 333.33333 3.75000 45.00000 291.66667 3.33333 44.58333 250.00000 2.91667 44.16667 208.33333 2.50000 43.75000 166.66667 2.08333 43.33333 125.00000 1.66667 42.91667 83.33333 1.25000 42.50000 41.66667 0.83333 42.08333 0.00000 0.41667
E sommando le rate si ottiene un importo totale di 532.50 euro.
Soluzione
calcola_amm.m – funzione
function [rata residuo interessi] = calcola_amm(finanziamento, tasso, anni) % il tasso è da dividere per il numero di mesi in ogni anno, %perchè la rata è mensile tasso = (tasso/12)/100; % la quota capitale è fissa ogni mese n_rate = anni*12; qc = finanziamento/(n_rate); % il capitale residuo è pari, ogni mese, al finanziamento meno %k * qc, dove k è il numero del mese corrente residuo(1:n_rate) = finanziamento - [1:n_rate] * qc;
Corso di Informatica B/C 2014-‐15 2-‐39
% gli interessi del primo mese sono basati sul finanziamento % iniziale interessi(1) = finanziamento * tasso; % mentre per i seguenti 2:n_rate-1 si prende semplicemente il % residuo e lo si moltiplica per il tasso interessi(2:n_rate) = residuo(1:n_rate-1) * tasso; % per la rata si somma quota capitale e interessi rata(1:n_rate) = qc + interessi(1:n_rate); end
14. Data una serie di misurazioni i cui valori misurati sono contenuti in un vettore x e i relativi pesi sono contenuti in un vettore w (delle stesse dimensioni di x), la media pesata si calcola come segue:
Si risponda ai seguenti quesiti utilizzando il linguaggio MATLAB.
• Scrivere una funzione mediaPesata avente come argomenti i vettori x e w e come risultato la media pesata.
• Scrivere una funzione mediaPesataSpeciale con parametri analoghi alla precedente, ma che calcoli la media pesata considerando come zeri i pesi relativi alle misurazioni con il valore minimo e il valore massimo.
• Si consideri una matrice Z di dimensione 2xN precedentemente definita in cui le colonne rappresentano le N misurazioni, la prima riga contiene i valori di ogni misurazione e la seconda riga i relativi pesi. Si scriva uno script per trovare gli indici delle misurazioni con valore compreso tra la media pesata e la media pesata speciale (estremi inclusi).
Soluzione
% punto 1 function r = mediaPesata(x,w) r = sum(x.*w)/sum(w);
% punto 2 function r = mediaPesataSpeciale(x,w) % Creazione di un vettore logico che contiene true in corrispondenza % del valore minimo selmin = (min(x) == x); % Creazione di un vettore logico che contiene true in corrispondenza % del valore massimo selmax = (max(x) == x); % Metto a 0 il peso delle celle che contrengono il valore minimo o % quello massimo
x̄ =w1 ⇤ x1 + w2 ⇤ x2 + · · ·+ wn ⇤ xn
w1 + w2 + · · ·+ wn
Corso di Informatica B/C 2014-‐15 2-‐40
w(selmin | selmax)=0; % Calcolo la media usando la funzione sviluppata al punto 1. % Avendo messo a 0 i pesi delle celle che non interessano sto % efffettivamente calcolando la media richiesta al punto 2. r = mediaPesata(x,w);
% punto 3 x = Z(1,:); % Selezione valore misurazioni w = Z(2,:); % Selezione pesi misurazioni mp = mediaPesata(x,w); mps = mediaPesataSpeciale(x,w); if mp <= mps % Selezione delle celle che hanno una misurazione compresa tra % media pesata e media pesata speciale sel = x >= mp & x <= mps; else % Selezione delle celle che hanno una misurazione compresa tra % media pesata speciale e media pesata (l'inverso del punto % precedente) sel = x >= mps & x <= mp; end % Selezione l'indice/posizione delle celle che soddisfano una delle %due situazioni analizzate nei passi precedenti find(sel)
15. Si scriva in linguaggio MATLAB una funzione controllaMultipli che prende in ingresso una matrice M di numeri interi strettamente maggiori di zero e un numero intero positivo n, e restituisce al programma chiamante un vettore colonna V avente lo stesso numero di righe della matrice M. La funzione determina, per ogni riga della matrice M, qual è il massimo numero di valori multipli di n che compaiono consecutivamente in colonne adiacenti della riga della matrice M e assegna tale numero alla posizione corrispondente in V. Di conseguenza, l’i-‐esimo elemento del vettore V conterrà il massimo numero di valori multipli di n consecutivi nell’i-‐esima riga della matrice M.
Ad esempio:
La funzione restituisce questo particolare vettore V perché nella prima riga di M individua come multipli di 3 tre valori (12, 21, 6), di cui due (21 e 6) sono consecutivi, nella seconda riga
M =
2
6666664
12 19 4 21 69 18 6 5 183 11 9 3 911 12 5 6 413 1 4 23 17 12 4 9 18
3
7777775M =
2
6666664
12 19 4 21 69 18 6 5 183 11 9 3 911 12 5 6 413 1 4 23 17 12 4 9 18
3
7777775V =
2
6666664
233102
3
7777775n = 3
Corso di Informatica B/C 2014-‐15 2-‐41
individua come multipli di 3 quattro valori (9, 18, 6, 18), di cui tre (9, 18, 6) sono consecutivi, e cosi via fino all’ultima riga. Per determinare se un valore è multiplo di un altro si può utilizzare la funzione mod che restituisce il resto della divisione intera tra due numeri (per esempio, mod(5, 2) restituisce 1).
Si scriva, inoltre, uno script che crei una matrice con i valori dell’esempio e chiami la funzione controllaMultipli passando come parametro la matrice creata e il valore 3. Si faccia in modo che il risultato ottenuto venga stampato a schermo.
Soluzione
controllaMultipli.m -‐ function
function V = controllaMultipli( M , n ) [nRighe, nColonne] = size(M); V = zeros(nRighe,1); for riga = 1:1:nRighe conta = 0; for colonna = 1:1:nColonne if mod(M(riga,colonna),n) == 0 conta = conta + 1; else conta = 0; end V(riga) = max([V(riga),conta]); end end end
script
M = [12 19 4 21 6; 9 18 6 5 18; 3 11 9 3 9; 11 12 5 6 4; 13 1 4 23 1; 7 12 4 9 18]; controllaMultipli(M,3)
Corso di Informatica B/C 2014-‐15 3-‐42
Chapter 3 Ricorsione
1. Si implementi una versione ricorsiva dell’algoritmo di Euclide per il calcolo del Minimo Comune Divisore (MCD) di due numeri interi, considerando le seguienti relazioni: • se m = n, MCD(m,n) = m (caso base) • se m > n, MCD(m,n) = MCD(m-‐n, n) (ricorsione) • se m < n, MCD(m,n) = MCD(m, n-‐m) (ricorsione)
Soluzione
mcd.m -‐ funzione
function [M] = mcd(m, n, passo) % la variabile "passo" non e` parte della soluzione. if m == n M = m; else if m > n M = mcd(m-n, n, passo+1); else M = mcd(m, n-m, passo+1); end end % ----------------------------------------------------------- % Da qui in poi il codice non fa parte della soluzione % ----------------------------------------------------------- % % Questo codice verra` eseguito solo quando si arrivera` al caso base, % quindi quando "passo" assumera` come valore il numero di passi di ricorsione. % % stampo "passi volte" il carattere TAB per "visualizzare" a che punto % della ricorsione mi trovo for ii = 1:passo fprintf('\t'); end % stampo l'invocazione corrente fprintf('|--> mcd: m = %d, n = %d, passo = %d\n', m, n, passo); % ----------------------------------------------------------- end
Corso di Informatica B/C 2014-‐15 3-‐43
2. Scrivere una funzione che verifichi iterativamente se una stringa è palindroma. Scrivere poi una funzione che implementi la stessa funzionalità in modo ricorsivo.
Soluzione
palindroma_iterativa.m -‐ funzione
function [res] = palindroma_iterativa(par) res = 1; for ii = 1:length(par)/2 % questa linea non fa parte della soluzione fprintf('passo = %d: %c =?= %c\n',ii,par(ii),par(end-ii+1)); if par(ii) ~= par(end - ii + 1) res = 0; return; end end
palindroma_ricorsiva.m – funzione
function [res] = palindroma_ricorsiva(parola) % Caso base: stringhe di un carattere (o vuote sono palindrome) if length(parola) < 2 res = 1; else % controllo se gli estremi sono uguali % if parola(1) == parola(end) % Passo ricorsione: richiama palindroma_ricorsiva % su parola(2, end-1) res = palindroma_ricorsiva(parola(2:end-1)); % da qui, l'esecuzione e` bloccata fino a che la funzione % precedente non ritorna else res = 0; end end
Corso di Informatica B/C 2014-‐15 3-‐44
main.m – script per provare le funzioni
% parola palindroma R = 'abbAbba'; % parola non palindroma P = 'abbiibaia'; fprintf('-----------------------------------------------------\n'); % invocazione funzione iterativa palindroma_iterativa(R); fprintf('-----------------------------------------------------\n'); palindroma_iterativa(P); fprintf('-----------------------------------------------------\n'); % invocazione funzione ricorsiva palindroma_ricorsiva(R, 1); fprintf('-----------------------------------------------------\n');
Corso di Informatica B/C 2014-‐15 3-‐45
3. Si implementi una funzione iterativa (e una sua versione ricorsiva) per tradurre i caratteri di una stringa da minuscoli a maiuscoli. Assumere che la funzione riceva in ingresso una stringa di caratteri minuscoli. La traduzione viene effettuata semplicemente sottraendo 32 al carattere da tradurre, e applicando char().
Ad esempio:
> char('a'-‐32)
ans = 'A'
Soluzione
maiuscola_iterativa.m -‐ funzione
function S = maiuscola_iterativa(s) for ii = 1:length(s) S(ii) = char(s(ii) - 32); % la linea successiva non fa parte della soluzione fprintf('passo iterativo = %d: %c -> %c\n',ii,s(ii),S(ii)); end end % Nota: % anche se in questo esercizio era richiesta esplicitamente una % versione % iterativa, sappiate che è possibile realizzare la stessa % operazione % con una sola chiamata a char(s-32), dove "s" è la stringa.
maiuscola_ricorsiva.m -‐ funzione
function S = maiuscola_ricorsiva(s, passo) % % Passo è una variabile di supporto, per chiarire il concetto % di ricorsione; in particolare indica il passo ricorsivo % corrente (e.g., primo, secondo, terzo). % % Caso base: stringa di un carattere if length(s) < 2 S = [char(s(1) - 32)]; else S = [char(s(1) - 32) maiuscola_ricorsiva(s(2:end), passo+1)]; end
Corso di Informatica B/C 2014-‐15 3-‐46
% Alternativamente: % ---------------- % % Caso base: stringa vuota % if ~length(s) % S = []; % else % ...idem... % end % ----------------------------------------------------------- % da qui in poi il codice non fa parte della soluzione % ----------------------------------------------------------- for ii = 1:passo fprintf(' '); end fprintf('|--> maiuscola_ricorsiva(%s, %d)\n', s, passo); % ----------------------------------------------------------- % fine
main.m -‐ script per provare le funzioni
s = 'ciaocomestai'; fprintf('-----------------------------------------------------\n'); S = maiuscola_iterativa(s) fprintf('-----------------------------------------------------\n'); S = maiuscola_ricorsiva(s, 1) fprintf('-----------------------------------------------------\n');
Corso di Informatica B/C 2014-‐15 3-‐47
4. Dato un numero reale positivo si richiede di scrivere una funzione iterativa e la sua versione ricorsiva per tradurlo in notazione scientifica, ovvero in un numero reale e una potenza di 10. Per esempio: 12345.1 diventa 1.23451 e 10^4.
Soluzione
notazione_scientifica.m – funzione
function [num, exp] = notazione_scientifica(n) if n <=10 num = n; exp = 0; else c = 0; while n >= 10 n = n/10; % dividiamo il numero per 10 c = c + 1; end num = n; exp = c; end
notazione_scientifica_ricorsivia.m – funzione
function [num, exp] = notazione_scientifica_ricorsiva(n,c) % quando si richiama questa funzione bisogna passarle c = 0 if n <=10 num = n; exp = c; else if n >=10 n = n/10; [num, exp] = notazione_scientifica_ricorsiva(n, c+1) end end
Corso di Informatica B/C 2014-‐15 3-‐48
5. Un metodo per calcolare il valore approssimato x(n) della radice quadrata di un numero reale non negativo Z, detto metodo babilonese, utilizza la seguente relazione ricorsiva:
con
Dove n è un intero non negativo arbitrario, mentre x(n) è l'approssimazione della radice quadrata di z.
Per esempio, se si vuole calcolare la radice quadrata approssimata di Z = 2 e si sceglie di farlo con n = 3, il valore di x(n=3) ottenuto con il metodo babilonese è 1.4142. Variando n si ottengono diverse approssimazioni della radice di z, ma varia anche il numero di ricorsioni per ottenere tali approssimazioni.
L'errore di approssimazione si ottiene con: e decresce al crescere di n.
• Scrivere una funzione ricorsiva sqrt1(z,n) che restituisca un'approssimazione della radice quadrata ed il relativo errore. Quando n = 0 si assuma che l'errore sia pari a inf.
• Scrivere una funzione sqrt2(z,err) che, utilizzando la funzione sqrt1, restituisca un valore approssimato della radice quadrata di z con un errore di approssimazione non superiore al valore err fornito come parametro.
Soluzione
sqrt1.m -‐ funzione
function [r err] = sqrt1(z, n) if n == 0 % caso base err = inf; r = 1; elseif n > 0 % ricorsione [r_temp err_temp] = sqrt1(z, n-1); % passo ricorsivo % calcolo di x(n) r = (r_temp + z / r_temp)/2; % x(n) = (x(n-1)+z/x(n-1))/2 % dove x(n-1) = r_temp % calcolo di err(n) err = abs(r - r_temp); % scostamento end
x(n) =1
2⇥ (x(n� 1) +
Z
x(n� 1))
x(0) = 1
err(n) = |x(n)� x(n� 1)|
Corso di Informatica B/C 2014-‐15 3-‐49
sqrt2.m -‐ funzione
function r = sqrt2(z, err) n = 0; err_temp = inf; % errore inizialmente infinito % cerco n tale che err_temp <= err while err_temp > err % condizione negata n = n + 1; [r err_temp] = sqrt1(z, n); end
6. Si dica cosa calcola la seguente funzione ricorsiva: a. Quando si passano i parametri 7 e 8. b. In generale.
function z = mistero(x) if x >= 1 z = mod(x,2) + 10*mistero(floor(x/2)); else z = 0; end Soluzione
La figura qui sotto mostra come avvengono le chiamate ricorsive. In particolare viene mostrato in ogni
blocco l'ambiente locale di esecuzione associato ad ogni chiamata.
1. mistero(7)=111, mistero(8)=1000
2. mistero(x) calcola un valore numerico in base 10 la cui sequenza di cifre può essere interpretata come rappresentazione del numero naturale x nel sistema binario.
Corso di Informatica B/C 2014-‐15 3-‐50
7. Si spieghi cosa fa la seguente funzione, fornendo *anche* degli esempi di output a fronte di alcuni esempi di input
Soluzione
function r = misteriosa(array) k = size(array, 2); % come se fosse length(array) % assumendo vettori riga if (k == 1) % caso base 1: se ha una sola cella r = 1; % ritorno 1 elseif (k == 2) % caso base 2: se invece ha due celle if (array(1) + array(2) == 10)
% se la prima e la seconda cella == 10 r = 1; % ritorna 1 else r = 0; % altrimenti ritorna 0 end else % se invece ha > 2 celle if (array(1) + array(k) == 10)
% se la prima + ultima cella == 10 r = misteriosa(array(2:k-1));
% passo ricorsivo sul vettore 2:k-1 else r = 0; % ritorna 0 end end % controlla se un vettore di interi, scansito dall'esterno verso % l'interno ha % tutte celle opposte che sommano a 10: se sì ritorna 1,altrimenti 0. misteriosa([1 9 3 2 8 7 1 9]) % ci aspettiamo 1 misteriosa([1 9 3 2 8 7 2]) % ci aspettiamo 0 misteriosa([1]) % 1 misteriosa([1 2]) % 0
function r = misteriosa(array) k = size(array, 2); if (k == 1) r = 1; elseif (k == 2) if (array(1) + array(2) == 10) r = 1; else r = 0; end else if (array(1) + array(k) == 10) r = misteriosa(array(2:k-1)); else r = 0; end end
Corso di Informatica B/C 2014-‐15 3-‐51
8. (TdE) Si consideri la seguente funzione:
function [ris] = s(n) if n<1 ris = -1; elseif n>=1 && n<=4 %* ris = n; %* else ris = s(n-2)*s(n-4); end
e lo script che la richiama:
% script s1 che richiama s for x = 1:8 fprintf('%d, ', s(x)); end
• Quali risultati vengono stampati a video? Si supponga di rimuovere le righe di codice evidenziate da un asterisco:
• La terminazione della ricorsione è ancora garantita per ogni valore dell’argomento n? In caso affermativo giustificare brevemente la risposta, in caso negativo riportare almeno un esempio di argomento in cui la ricorsione non termina.
• Con la modifica apportata quali risultati vengono stampati a video?
Si forniscano opportune giustificazioni per tutte le risposte.
Soluzione
Soluzione
• Per x compreso tra 1 ed 8 il programma calcola e stampa la seguente sequenza di numeri 1, 2, 3, 4, 3, 8, 9, 32. Infatti: s(1) = 1 s(2) = 2 s(3) = 3 s(4) = 4 s(5) = s(3)*s(1) = 3*1 = 3 s(6) = s(4)*s(2) = 4*2 = 8 s(7) = s(5)*s(3) = 3*3 = 9 s(8) = s(6)*s(4) = 8*4 = 32
• La ricorsione termina sempre, dato che per qualsiasi argomento la funzione viene richiamata su argomenti sempre minori fino a raggiungere il caso base: un argomento minore o uguale a zero
• La nuova sequenza è 1, 1, -‐1, -‐1, -‐1, -‐1, 1, 1 . Infatti:
s(1) = s(-‐1)*s(-‐3) = (-‐1)*(-‐1) = 1 s(2) = s(0)*s(-‐2) = (-‐1)*(-‐1) = 1
Corso di Informatica B/C 2014-‐15 3-‐52
s(3) = s(1)*s(-‐1) = (1)*(-‐1) = -‐1 s(4) = s(2)*s(0) = (1)*(-‐1) = -‐1 s(5) = s(3)*s(1) = (-‐1)*(1) = -‐1 s(6) = s(4)*s(2) = (-‐1)*(1) = -‐1 s(7) = s(5)*s(3) = (-‐1)*(-‐1) = 1 s(8) = s(6)*s(4) = (-‐1)*(-‐1) = 1
9. (TdE) Si considerino la funzione e lo script seguenti:
function†[r]†=†MiaFunz(a,†b) if b == 0 r=1; else r = a * MiaFunz(a, b-1); end;
%script che chiama MiaFunz x=2; for y = 0:1:4 r = MiaFunz(x,y) end
• Descrivere brevemente quale sia la funzione matematica calcolata dalla funzione MiaFunz. Giustificare la risposta.
• Quali risultati vengono stampati a video? Non è necessario calcolare i valori numerici esatti, ma è sufficiente riportare le espressioni aritmetiche necessarie per calcolarli. Giustificare la risposta.
Soluzione
La funzione matematica calcolata dalla funzione MiaFunz(a,b) è ab, sotto l'ipotesi che b≥0 I risultati stampati a video sono: 20=1
21=2
22=4
23=8
24=16
Corso di Informatica B/C 2014-‐15 3-‐53
10. Si consideri una matrice triangolare T, rappresentante il famoso triangolo di Tartaglia, i cui valori, identificati dal loro numero di riga e di colonna a>b, sono definiti nel seguente modo:
T(a,1) = 1 T(a,a) = 1 T(a,b)=T(a-1,b-1)+T(a-1,b) Ad esempio, le prime 5 righe della matrice triangolare T sono le seguenti:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Si scriva una funzione ricorsiva che, utiizzando la definizione sopra, permetta di calcolare il valore di un generico elemento della matrice T.
Soluzione
La soluzione a questo quesito puo' essere determinata facilmente in quanto dalla definizione e' possibile ricavare il caso base e il caso ricorsivo della ricorsione.
Rappresentiamo T come una funzione che ha come argomenti la riga e la colonna e come risultato il valore contenuto nella matrice (che dobbiamo calcolare).
CASO BASE: T(a,1)=1 e T(a,a)=1
Questo caso base ci dice che se il secondo parametro della funzione e' uguale a 1, oppure uguale al primo parametro, il risultato sara' 1 e si termina la ricorsione.
CASO RICORSIVO: T(a,b)=T(a-1,b-1)+T(a-1,b)
Questo caso ricorsivo ci dice che in tutti gli altri casi, il risultato si calcola chiamando ricorsivamente la funzione.
function ris = tartaglia(a,b) if b == 1 || a == b ris = 1; else ris = tartaglia(a-1,b-1)+tartaglia(a-1,b); end
Corso di Informatica B/C 2014-‐15 3-‐54
11. Si scrivano in linguaggio MATLAB: • una funzione ricorsiva che calcoli il risultato della divisione intera a/b. • una funzione ricorsiva che calcoli il resto della divisione intera a/b. • una funzione ricorsiva che calcoli sia il risultato sia il resto della divisione intera a/b.
Suggerimento:
a/b = 1+(a-b)/b
Soluzione
Caso 1
function risultato = divisione(a,b) if a >= b risultato = 1 + divisione(a-b,b); else risultato=0; end
Caso 2
function r = resto(a,b) if a >= b r = resto(a-b,b); else r = a; end
Caso 3
function [risultato, resto] = divisioneresto(a,b) if a>=b [risultato1, resto1] = divisioneresto(a-b,b); risultato = risultato1 + 1; resto = resto1; else risultato=0; resto=a; end
Corso di Informatica B/C 2014-‐15 3-‐55
12. Si scriva una funzione in MATLAB che abbia come parametro di ingresso un vettore contente un insieme di valori, e stampi tutte le permutazioni di tali valori. Ad esempio, se i valori sono [1 2 3], considerando questo schema:
1 2 3 (primo numero) / \ / \ / \ 2 3 1 3 1 2 (possibili secondi numeri) | | | | | | 3 2 3 1 2 1 (possibili terzi numeri)
Le permutazioni di [1 2 3] sono:
[1 2 3], [1 3 2], [2 1 3], [2 3 1], [3 1 2], [3 2 1].
Soluzione
Osservando lo schema possiamo notare che abbiamo bisogno di due informazioni: 1) i valori già considerati precedentemente nelle permutazioni (per non ripeterli) e i valori ancora disponibili (da aggiungere). Questo fa sì che la nostra funzione ricorsiva debba avere due parametri d’ingresso: 1) l'insieme dei valori già inseriti nella permutazione e 2) l'insieme dei valori ancora da inserire.
Poiché' la funzione richiesta dall'esercizio ha un solo parametro, cioè l'insieme dei valori da inserire nella permutazione, avremo bisogno di creare due funzioni. La prima con un solo parametro contenente i valori da inserire, e la seconda con due parametri contenenti i valori già inseriti nella permutazione e quelli ancora da inserire.
La prima funzione avrà solo lo scopo di nascondere a chi la invoca che c’è un parametro in più. Questa funzione chiamerà la seconda funzione passando un insieme vuoto come valori già inseriti, e tutti i valori disponibili come valori da inserire.
La funzione ricorsiva sarà strutturata in questo modo:
CASO BASE
L'insieme dei valori da inserire è vuoto: stampo semplicemente i valori già inseriti (primo parametro) e termino.
CASO RICORSIVO
L'insieme dei valori da inserire non è vuoto: scandisco tutti i possibili valori ancora da inserire ed eseguo un’invocazione ricorsiva della funzione per ognuno di questi valori. In queste invocazioni ricorsive passo come primo parametro i valori già inseriti dal chiamante, più quello nuovo che sto scandendo. Come secondo parametro invece passo tutti i valori ancora da inserire, eccetto quello che sto scandendo.
Corso di Informatica B/C 2014-‐15 3-‐56
Codice
function p=permutazioni(m) permuta([],m);
function ris=permuta(p, m) if length(m)>0 for k=1:length(m) permuta([p m(k)], m([1:k-1 k+1:end])); end else p end
Corso di Informatica B/C 2014-‐15 3-‐57
13. Il Sudoku è un gioco di logica nel quale al giocatore viene proposta una griglia di 9×9 celle, ciascuna delle quali può contenere un numero da 1 a 9, oppure essere vuota; la griglia è suddivisa in 9 righe orizzontali, nove colonne verticali e in 9 "sottogriglie", chiamate regioni, di 3×3 celle contigue. Scopo del gioco è quello di riempire le caselle bianche con numeri da 1 a 9, in modo tale che in ogni riga, colonna e regione siano presenti tutte le cifre da 1 a 9 e, pertanto, senza ripetizioni. L’esempio sotto riportato mostra una griglia Sudoku corretta.
Si vuole realizzare un programma in grado di verificare se una griglia assegnata rispetta le regole del gioco.
• Si implementi la funzione verificaBase, che prenda in ingresso una vettore riga La funzione restituisca 1 se il vettore v contiene tutti i numeri compresi tra 1 e 9.
• Si implementi la funzione verificaRighe, che riceva in ingresso una matrice 9x9 rappresentante una soluzione del Sudoku e restituisca 1 se le righe della matrice Sudoku passata come parametro rispettano le regole del gioco.
• Si implementi la funzione verificaColonne, che riceva in ingresso una matrice 9x9 rappresentante una soluzione del Sudoku e restituisca 1 se le colonne della matrice Sudoku passata come parametro rispettano le regole del gioco.
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
Corso di Informatica B/C 2014-‐15 3-‐58
• Si implementi la funzione verificaRegioni, che riceva in ingresso una matrice 9x9 rappresentante una soluzione del Sudoku e restituisca 1 se le 9 regioni della matrice sudoku passata come parametro rispettano le regole del gioco.
• Si implementi infine la funzione verificaSudoku, , che riceva in ingresso una matrice 9x9 rappresentante una soluzione del Sudoku e restituisca 1 se la matrice sudoku passata come parametro, rispetta tutte le regole del gioco
Soluzione
verificaBase.m -‐ funzione
function [ ris ] = verificaBase( v ) ris = 0;
l = length(v);
for ii =1:l
if isempty(find(v==ii))
return ;
end
end
ris =1;
Corso di Informatica B/C 2014-‐15 3-‐59
verificaRighe.m – funzione
function [ ris ] = verificaRighe( sudoku ) [r c] = size(sudoku);
���for ii=1:r
riga = sudoku(ii ,:); ���
ris = verificaBase(riga);
if ris == 0
return
end
end
verificaColonne.m – funzione
function [ ris ] = verificaColonne ( sudoku) ris = verificaRighe(sudoku');
Corso di Informatica B/C 2014-‐15 3-‐60
verificaRegioni.m – funzione
function [ ris ] = verificaRegioni( sudoku )
[r c] = size(sudoku); ���
for ii = 1:3:r-2
for jj =1:3:c ���-2
subM=sudoku(ii:ii+2, jj:jj+2);
ris = verificaBase (subM(:) ) ;
if ris == 0
return
end
end
end
verificaSudoku.m – funzione
function [ ris ] = verificaSudoku( sudoku)
ris = verificaRighe (sudoku) ;
���if ris==0
disp('La matrice viola le regole di riga');
return
end
ris = verificaColonne (sudoku) ;
Corso di Informatica B/C 2014-‐15 3-‐61
if ris==0
disp ('La matrice viola le regole di colonna') ;
return
end
ris = verificaRegioni (sudoku) ;
if ris==0
disp('La matrice viola le regole di regione');
return
end
disp('Matrice OK!');
Corso di Informatica B/C 2014-‐15 4-‐62
Chapter 4 Accesso ai file
1. Un'agenzia di viaggi possiede un proprio database di destinazioni e di acquisti effettuati. Il database e' composto da due file: il primo ‘dest.dat’ in ogni riga ha il nome della destinazione e il prezzo; il secondo ‘acquisti.dat’ in ogni riga ha il nome del cliente e il nome della destinazione dell'acquisto effettuato.
• Si scriva uno script che carichi il database. • Si stampi il fatturato generato da ogni destinazione.
Soluzione
% parte 1 [dest_nome, dest_costo] = textread('dest.dat','%s %f') [acquisti_nome, acquisti_dest]= textread('acquisti.dat','%s %s') % parte 2 for ii=1:size(dest_nome) fatturato=0; for jj=1:size(acquisti_dest) if strcmp(acquisti_dest(jj),dest_nome(ii)) % strcmp restituisce 1 se sono uguali, 0 se sono diversi % In C e' il contrario!!! fatturato = fatturato + dest_costo(ii); end end disp(['Fatturato per ', est_nome(ii), ': ', num2str(fatturato)]); end
Corso di Informatica B/C 2014-‐15 5-‐63
Chapter 5 Diagrammi 1. Si disegni la superficie del paraboloide iperbolico dato dalla seguente equazione:
z=x.^2-y.^2 per valori di x e y nell'intervallo [-5,+5]. Impostare titoli ed etichette.
Soluzione
Assegno innanzitutto (come nei grafici a due dimensioni) vari valori nell'intervallo da -‐5 a +5 (separati da micro intervalli di dimensione opportuna) alle variabili x e y. Più piccoli sono tali intervalli e più definito sarà il grafico. Dopodiché' creo con la funzione meshgrid le matrici xx e yy contenenti la prima i valori di x ripetuti length(y) volte, la seconda i valori di y' ripetuti length(x) volte. La coppia di queste matrici identifica la griglia rettangolare che sarà utilizzata per modellare la superficie identificata da zz (più piccoli sono gli intervalli di x e y e più fitta sarà la griglia). La matrice zz si calcola da xx e yy utilizzando direttamente l'equazione della funzione a due variabili da rappresentare (zz=xx2-yy2 in questo caso). Infine, le tre matrici ottenute (xx,yy,zz) saranno i parametri dell'istruzione mesh che disegnerà il grafico.
x=-5:0.05:5; y=x; [xx yy]=meshgrid(x,y); zz=xx.^2-yy.^2; mesh(xx,yy,zz); title('Paraboloide iperbolico') xlabel('Asse x') ylabel('Asse y') zlabel('Asse z') Risultato