18 minutes
04 - Compito in classe
Per completezza, si rimanda al primo post del sito per ulteriori informazioni.
Si ricorda che dello stesso esercizio possono esistere più varianti.
Esercizio 1
Si scriva la funzione ricorsiva sommaPari(a), che prende come parametro un array a di interi e restituisce la somma degli elementi pari.
Esempi:
sommaPari([5,9,1,-4,3,6,2,-5]) → 4
sommaPari([5,9,1,33,7,-3]) → 0
function sommaPariR(a,i = 0) {
if (!(i < a.length))
return 0;
return (a[i] % 2 == 0 ? a[i] : 0) + sommaPariR(a,++i);
}
Esercizio 2
Si scriva una funzione map(f,a), dove f è una funzione che prende come argomento un intero e restituisce un valore numerico, e a è un array di interi. map (f,a) restituisce l’array il cui i-esimo elemento è il risultato dell’applicazione di f all’i-esimo elemento di a.
Esempi:
map(x => x*x, [1,2,3,4,5,6]) → [1,4,9,16,25,36]
map (x => Math.sqrt(x),[1,2,3,4,5,6]) → [1,1.4142135623730951,1.7320508075688772,2,2.23606797749979,2.449489742783178]
map(x => x++, [1,2,3,4,5,6]) → [1,2,3,4,5,6]
map(x => ++x, [1,2,3,4,5,6]) → [2,3,4,5,6,7]
function map(f, a) {
return a.map(f);
}
// oppure
function map(f, a) {
for (var i in a)
a[i] = f(a[i])
return a;
}
Esercizio 3
Si scriva una funzione filter(f,a), dove f è una funzione che prende come argomento un intero e restituisce un valore booleano, e a è un array di interi. filter (f,a) restituisce l’array in cui sono presenti solo i valori per cui f restituisce true, nell’ordine in cui compaiono in a.
Esempi:
filter(x => x>0, [10,4,-90,21,-1]) → [10,4,21]
filter(x => x<0, [10,4,-90,21,-1]) → [-90,-1]
function filter(f, a) {
return a.filter(elem => f(elem))
}
// oppure
function filter(f, a) {
let res = [];
for (var elem of a)
if (f(elem))
res.push(elem)
return res;
}
Esercizio 4
Si scriva una funzione similitudine(a,b), con a e b stringhe. La funzione restituisce un oggetto che contiene come chiavi i caratteri che compaiono nelle due stringhe alla stessa posizione, e come valore la posizione corrispondente.
Esempi:
similitudine(“The Holy Grail”, “Life of Brian”) → {o: 5, a: 11}
Se lo stesso carattere appare più volte in entrambe le stringhe nella stessa posizione, per esempio “pippo” e “pappa”, va bene restituire una qualunque delle posizioni in cui appare (nell’esempio: {p: 0} o {p: 2} o {p: 3}).
function similitudine(a,b) {
let obj = {};
for (let i in a) {
if (a[i] == b[i])
obj[a[i]] = i;
}
return obj;
}
Esercizio 5
Si scriva una funzione tombola(a,b) che prende come argomenti due array di interi positivi (>0) distinti (senza ripetizioni). se nessun intero in a compare in b, le funzione restituisce (esattamente) la stringa “ritenta”; se solo un intero in a compare in b, le funzione restituisce (esattamente) la stringa “ritenta”; se due interi in a compaiono in b, la funzione restituisce (esattamente) la stringa “ambo”; se tre interi in a compaiono in b, la funzione restituisce (esattamente) la stringa “terno”; in tutti gli altri casi restituisce (esattamente) la stringa “tombola”.
Esempi:
tombola([1,17,4,90],[4,17,33,89,32]) → ‘ambo’
tombola([1,17,4,90],[6,27,33,89,32]) → ‘ritenta’
tombola([1,17,4,90],[1,27,4,89,32,90,17]) → ‘tombola’
function tombola(a,b) {
let count = 0;
for (let elem of a) {
if (b.includes(elem))
count++;
}
switch(count) {
case 0:
return "ritenta"
case 1:
return "ritenta"
case 2:
return "ambo"
case 3:
return "terno"
default:
return "tombola"
}
}
Esercizio 6
Le somme prefisse di una sequenza di interi x0, x1, …, xn sono una sequenza di interi y0, y1, …, yn tali che y0 = x0, y1= x0+x1, y2 = x0+x1+x2, …, yn = x0+x1+x2+…+xn.
Si scriva una funzione sommeP(a) che prende come argomento un’array a di interi e restituisce un array contenente le somme prefisse degli elementi di a.
Esempi:
sommeP([1,2,3,4,5,6]) → [1,3,6,10,15,21]
sommeP([0,2,4,4,2,0,-2,-4,-6]) → [0,2,6,10,12,12,10,6,0]
function sommeP(a) {
let newArr = new Array(a.length)
newArr[0] = a[0];
for (let i = 1; i < a.length; i++) {
let sum = 0;
for (let j = 0; j <= i; j++) {
sum += a[j];
}
newArr[i] = sum;
}
return newArr;
}
Esercizio 7
Si scriva una funzione decifra(s,k) con s una stringa cifrata e k un intero positivo. La funzione restituisce la corrispondente stringa decifrata utilizzando k (la chiave). La decriptazione segue le regole del cifrario di Cesare applicate alla codifica UNICODE dei caratteri. In particolare: data una lettera c della stringa cifrata questa viene sostituite dalla lettera che si trova k posizioni prima nella codifica UNICODE. Ad esempio, la lettera ‘e’ viene decrittata nella lettera ‘c’ quando la chiave k è uguale a 2; si assuma che la stringa contenga solo lettere minuscole dell’alfabeto (inglese), oppure il carattere spazio; il carattere spazio va lasciato inalterato.
Attenzione: se nel tornare indietro di k posizioni finite fuori dall’alfabeto (prima della lettera ‘a’) ricominciate dal fondo (dalla ‘z’). Ad esempio la lettera criptata ‘a’ viene decriptata con ‘y’ quando k è uguale a 2; ‘a’ viene decriptata con ‘z’ se k = 1). SUGGERIMENTO: il codice UNICODE per ‘a’ e' 97. Si usino le funzioni s.charCodeAt() e String.fromCharCode().
Esempi:
decifra(“hal”,25) → ‘ibm’
decifra(“hal zzzz”,25) → ‘ibm aaaa’
Esercizio 8
Si scriva una funzione verificaSomma(a) che prende come parametro un array di interi. La funzione restituisce true se ogni elemento di a (tranne il primo) è pari alla somma degli elementi che lo precedono, e false altrimenti.
Esempi:
verificaSomma([1, 2, 6, 10, 32]) → false
verificaSomma([1, 1, 2, 4, 8]) → true
function verificaSomma(a) {
for (let i = 1; i < a.length; i++) {
let sum = 0;
for (let j = 0; j < i; j++) {
sum += a[j]
}
if (sum != a[i])
return false;
}
return true;
}
Esercizio 9
Si scriva una funzione frequenzaC(s) che, preso come parametro una stringa s, restituisca un dizionario le cui chiavi sono i caratteri contenuti in s e i cui valori il numero di volte che quel carattere compare nella stringa (anche il carattere spazio va considerato).
Esempi:
frequenzaC(“i vitelli dei romani sono belli”) → {i: 6,' ‘: 5,v: 1,t: 1,e: 3,l: 4,d: 1,r: 1,o: 3,m:1,a: 1,n: 2,s: 1,b: 1}
frequenzaC(“La forzA sia con te!") → {L: 1,a: 2,’ ‘: 4,f: 1,o: 2,r: 1,z: 1,A: 1,s: 1,i:1,c: 1,n: 1,t: 1,e: 1,’!': 1}
function frequenzaC(s) {
let freq = s.split('');
let obj = {};
for (let char of freq) {
let count = freq.filter((elem) => elem == char).length;
obj[char] = count;
}
return obj;
}
Esercizio 10
Si scriva una funzione contaDispari(T) che dato un albero binario (i cui nodi sono implementati come visto a lezione come oggetti con chiavi val, sx e dx) restituisca il numero di nodi contenente un valore dispari.
Esempi:
contaDispari({val:7,sx:{val: 4, sx: {val: 3}, dx: {val:12, sx: {val: 4, dx:{val:3}, sx:{val: 8}}}}, dx:{val: 11, dx: {val: 3}, sx: {val:8, sx: {val: 6}}}}) → 5
contaDispari({val:8,sx:{val: -4, sx: {val: 33}, dx: {val:13, sx: {val: 4, dx:{val:-3}, sx:{val: 81}}}}, dx:{val: 11, dx: {val: 3}, sx: {val:8, sx: {val: 63}}}}) → 7
contaDispari({val:8,sx:{val: -4, sx: {val: 32}, dx: {val:12, sx: {val: 2, dx:{val:-2}, sx:{val: 812}}}}, dx:{val: 112, dx: {val: 32}, sx: {val:82, sx: {val: 632}}}}) → 0
function contaDispari(T) {
if (T == undefined)
return 0;
return (T.val % 2 != 0 ? 1 : 0) + contaDispari(T.sx) + contaDispari(T.dx);
}
Esercizio 11
Si scriva una funzione gby(data), che prende come argomento un array di dizionari (oggetti). Ogni dizionario rappresenta la carriera scolastica di uno studente. In particolare, ogni dizionario ha come chiave il nome di un insegnamento, e come valore il voto preso all’esame (che si assume essere >= 18).
Ad esempio, il seguente array contiene le carriere di 3 studenti: data = [{lab1:20, fi: 30},{analisi:28, lab1:30},{algebraL:28, ProgAlgo:30}]
La funzione gby(data) restituisce un dizionario le cui chiavi sono i nomi degli insegnamenti, e come valore la media dei voti presi da tutti gli studenti per quell’insegnamento.
Esempi:
gby([{lab1:20, fi: 30}, {analisi:28, lab1:30}, {algebraL:28, progAlgo:30, fi: 18}]) → {lab1: 25, fi: 24, analisi: 28, algebraL: 28, progAlgo: 30}
gby([{lab1:20, fi: 29}, {analisi:28, lab1:27}, {algebraL:28, progAlgo:30, fi: 18}]) → {lab1: 23.5, fi: 23.5, analisi: 28, algebraL: 28, progAlgo: 30}
function gby(data) {
let obj = {};
let n_studenti = {};
for (let o of data) {
for (let key in o) {
if (key in obj) {
obj[key] += o[key];
n_studenti[key]++;
} else {
obj[key] = o[key]
n_studenti[key] = 1;
}
}
}
for (let key in obj) {
obj[key] = obj[key]/n_studenti[key];
}
return obj;
}
Esercizio 12
Si scriva una funzione dna(s,a), che prende come argomento una stringa s ed un array di stringhe a, e restituisce un dizionario le cui chiavi sono tutte le stringhe in a. Il valore di una chiave c è l’array contenente tutte le posizioni in s da cui iniziano le occorrenze di c (se non ci sono occorrenze di c in s allora l’array sarà vuoto). Esempi:
dna(“actgcctgaactgactgaa”,[“act”,“cgt”,“aat”]) → {act: [0,9,13], cgt: [], aat: []}
dna(“actgcgtgaactgactgaa”,[“act”,“cgt”,“aat”]) → {act: [0,9,13], cgt: [4], aat: []}
dna(“actgcgtgaactgactgaa”,[“act”,“ctg”,“tga”]) → {act: [0,9,13], ctg: [1,10,14], tga: [6,11,15]}
PS: Non è detto che le stringhe in a siano sempre di 3 caratteri.
function dna(s,a) {
let obj = {};
for (let elem of a) {
obj[elem] = [];
}
for (let elem of a) {
let index = s.indexOf(elem);
if (index != -1)
obj[elem].push(index);
while (index != -1) {
index = s.indexOf(elem,index+1);
if (index != -1)
obj[elem].push(index);
}
}
return obj;
}
Esercizio 13
Un ospedale possiede dati genetici di pazienti, dove ogni paziente è rappresentato dal numero di mutazioni su un set di geni. Possiamo rappresentare il paziente come un oggetto dove le chiavi sono i geni e i valori il numero di mutazioni. Per esempio paz1 = {“TP53”:10, “BRC1”:20, “RAS”:0,“MAPK”:3} rappresenta un paziente che presenta mutazioni su 4 geni. Un pathway è un insieme di geni. Per esempio pat1 = {“TP53”:1, “RAS”:1, “BRC1”:1} rappresenta un pathway con 3 geni. Dato un paziente paz, si definisce il livello di mutazione di paz rispetto a un pathway pat come la media del numero di mutazioni di paz per ogni gene presente in pat. Se un gene presente in pat non esiste nei dati del paziente, si assume che quella mutazione abbia valore 0 per paz. Per esempio, per il paz1 dell’esempio riportato sopra,il livello di mutazione rispetto a pat1 è 10, risultante dalla media tra 10 (valore di TP53), 0 (valore di RAS) e 20 (valore di BRC1). Si scriva una funzione analisiPathway(pazienti, path) che prende due parametri: un array di pazienti e un pathway. La funzione restituisce un array con il livello di mutazione di quel pathway per ogni paziente presente nell’array (nell’array restituito, il valore in posizione i corrisponde al livello di mutazione per il paziente i).
Esempi:
analisiPathway([{“TP53”:10, “BRC1”:20, “RAS”:0,“MAPK”:3},{“TP53”:12, “MAPK”:3}, {“TP53”:1, “RAS”:1,“BRC1”:7},{“RASK”:1,“CLN”:1,“MAPK”:1}],{“TP53”:1,“RAS”:1,“BRC1”:1}) → [10,4,3,0]
analisiPathway([{“TP53”:10, “BRC1”:20, “RAS”: 60, “MAPK”:3}, {“TP53”:6}, {“TP53”:3,“RAS”:3,“BRC1”:7}],{“TP53”:1,“RAS”:1,“BRC1”:1}) → [30,2,4.333333333333333]
function analisiPathway(pazienti, path) {
let arr = [];
for (let paz of pazienti) {
let media = 0;
let count = 0;
for (let key in paz) {
if (key in path) {
media += paz[key];
count++;
}
}
if (count != 0)
arr.push(media/Object.keys(path).length);
else
arr.push(0)
}
return arr;
}
Esercizio 14
Si scriva una funzione bisect(f,a,b), dove a e b sono valori numerici, e f è una funzione monotona, definita e continua nell’intervallo [a,b], e tale che f(a)*f(b) < 0. La funzione bisect(f,a,b) restituisce un valore x per cui |f(x)| <= 0,0001 (in altre parole, deve approssimare lo zero di f nell’intervallo [a,b] con una tolleranza di al più 0,0001).
NOTA: dato che bisect(f,a,b) restituisce una approssimazione dello zero di f, non è detto che il valore che trovate sia esattamente uguale a quello riportato negli esempi. Per essere considerata corretta, la vostra soluzione deve riportare un valore che si discosta al più di 0.0001 dallo zero di f in [a,b]).
Esempi:
bisect(x=>x**3, -1, 1) → 0
bisect(x=>x**3-x-2,1,2) → 1.52142333984375
bisect(x=>x*Math.cos(x),1,4) → 1.570831298828125
function bisect(f,a,b) {
let precision = 0.0001;
let middle = (a+b)/2;
if (Math.abs(f(middle)) < precision)
return middle;
if (f(middle) * f(a) < 0)
return bisect(f,a,middle)
return bisect(f,middle,b);
}
Esercizio 15
Diciamo che un nodo di un albero binario è in equilibrio se il suo valore è >= del valore del suo figlio sinistro (se esiste), ed è <= del valore del suo figlio destro (se esiste). Diciamo che un albero binario è in equilibrio se tutti i suoi nodi sono in equilibrio. Si scriva una funzione inEquilibrio(T) che dato un albero binario (i cui nodi sono implementati come visto a lezione come oggetti con chiavi val, sx e dx) restituisca true se T è in equilibrio, e false altrimenti.
Esempi:
inEquilibrio({val:7,sx:{val: 4, sx: {val: 3}, dx: {val:12, sx: {val: 4, dx:{val:8}, sx:{val: 2}}}}, dx:{val: 11, dx: {val: 18}, sx: {val:3, sx: {val: 2}}}}) → true
inEquilibrio({val:8,sx:{val: -4, sx: {val: 33}, dx: {val:13, sx: {val: 4, dx:{val:-3}, sx:{val: 81}}}}, dx:{val: 11, dx: {val: 3}, sx: {val:8, sx: {val: 63}}}}) → false
inEquilibrio({val:8}) → true
inEquilibrio({val:8,sx:{val: 8},dx:{val:8}}) → true
function inEquilibrio(T) {
if (T === undefined)
return true;
if (T.sx && T.sx.val > T.val)
return false;
if (T.dx && T.dx.val < T.val)
return false;
return inEquilibrio(T.sx) && inEquilibrio(T.dx);
}
Esercizio 16
Si scriva una funzione innestaSottoAlberi(T,sT) che prende come parametri due alberi binari T e sT, (i cui nodi sono implementati come visto a lezione come oggetti con chiavi val, sx e dx). La funzione sostituisce nell’albero T i sottoalberi ‘secchi’ con l’albero sT. Un sottoalbero è secco se il valore nella radice è < 0. Si assuma che sT non contiene sottoalberi secchi.
Esempi:
t={val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9}}}, dx:{val:-3, sx:{val:-8},dx:{val:7}}}
st={val:1, sx:{val:1}, dx:{val:1}}
Dopo la chiamata a innestaSottoAlberi(t,st), t contiene {val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9}}}, dx:{val:1, sx:{val:1}, dx:{val:1}}}
t={val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9}}}, dx:{val:-3, sx:{val:-8},dx:{val:7}}}
st={val: 0}
Dopo la chiamata a innestaSottoAlberi(t,st), t contiene {val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9}}}, dx:{val:0}}
function innestaSottoAlberi(T,sT) {
let found_sx = false;
let found_dx = false;
if (T === undefined)
return;
if (T.val < 0) {
T.val = sT.val;
T.dx = sT.dx;
T.sx = sT.sx;
return;
}
if (T.sx && T.sx.val < 0) {
innestaSottoAlberi(T.sx,sT)
found_sx = true;
}
if (T.dx && T.dx.val < 0) {
innestaSottoAlberi(T.dx,sT)
found_dx = true;
}
if (!found_dx && !found_sx) {
innestaSottoAlberi(T.sx);
innestaSottoAlberi(T.dx);
} else if (!found_dx)
innestaSottoAlberi(T.dx)
else
innestaSottoAlberi(T.sx)
}
Esercizio 17
Si scriva una funzione risolvi(eq) che prende come argomento un’equazione di primo grado ax+b=0, rappresentata come oggetto avente due proprietà, a e b. La funzione risolve l’equazione, e inserisce il risultato (cioe' il valore dell’incognita x) nell’oggetto eq, nella proprietà x. Si può assumere che a!=0 sempre.
La funzione non deve restituire nulla (no return).
Esempi:
eq = {a:9,b:18}
Dopo la chiamata a risolvi(eq), eq contiene {a:9, b:18, x:-2}
function risolvi(eq) {
// ax + b = 0 => x = -b/a
eq.x = -eq.b/eq.a;
}
Esercizio 18
Una biblioteca ha una collezione di libri con titolo, autore e numero di copie disponibili. Un libro è rappresentato mediante un oggetto avente 3 proprietà: titolo, autore, copie. La biblioteca viene rappresentata da un array di libri.
Si scriva una funzione prestito(biblioteca, s), con biblioteca un array di libri, e s una stringa che rappresenta il titolo di un libro. Se in biblioteca è presente un libro avente titolo s, quel libro viene dato in prestito: il numero di copie di quel libro in biblioteca viene decrementato, e la funzione restituisce true.
Se il libro non è disponibile (o non esiste in biblioteca, o non ci sono copie disponibili), la funzione restituisce false, e biblioteca non viene modificato.
Esempi:
biblioteca = [{titolo:‘Pride and Prejudice’,autore:‘Jane Austen’, copie:10}, {titolo: ‘Eloquent Javascript’,autore:‘Marijn Haverbeke’,copie:0},{titolo: ‘The lord of the rings’,autore:‘J. R. R. Tolkien.',copie:6}]
prestito(biblioteca,“The lord of the rings”) restituisce true e biblioteca contiene [{titolo:‘Pride and Prejudice’,autore:‘Jane Austin’, copie:10},{titolo: ‘Eloquent Javascript’,autore:‘Marijn Haverbeke’,copie:0},{titolo: ‘The lord of the rings’,autore:‘J. R. R. Tolkien.',copie:5}]
biblioteca = [{titolo:‘Pride and Prejudice’,autore:‘Jane Austen’, copie:10}, {titolo: ‘Eloquent Javascript’,autore:‘Marijn Haverbeke’,copie:0},{titolo: ‘The lord of the rings’,autore:‘J. R. R. Tolkien.',coppie:6}]
prestito(biblioteca,“Sense and Sensibility”) restituisce false e biblioteca non viene modificato.
biblioteca = [{titolo:‘Pride and Prejudice’,autore:‘Jane Austen’, copie:10}, {titolo: ‘Eloquent Javascript’,autore:‘Marijn Haverbeke’,copie:0},{titolo: ‘The lord of the rings’,autore:‘J. R. R. Tolkien.',copie:6}]
prestito(biblioteca,‘Eloquent Javascript’) restituisce false e biblioteca non viene modificato.
function prestito(biblioteca,s) {
for (let libro of biblioteca) {
if (libro['titolo'] == s) {
// controllo della disponibilità
if (libro['copie'] <= 0)
return false;
else {
libro['copie']--;
return true;
}
}
}
return false;
}
Esercizio 19
Si scriva una funzione tagliaAlberi(T), che prende come parametro un albero binario T (i cui nodi sono implementati come visto a lezione come oggetti con chiavi val, sx e dx). La funzione taglia i sottoalberi ‘secchi’. Un sottoalbero è secco se il valore nella radice del sottoalbero è < 0. Il taglio avviene eliminando il contenuto del nodo secco - le proprietà val, sx e dx (si vedano gli esempi). La funzione non deve restituire nulla (no return).
Esempi:
t={val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9} } }, dx:{val:-3, sx:{val:-8},dx:{val:7}}}
Dopo la chiamata a tagliaAlberi(t), t contiene {val:20, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9} } }, dx:{}}
t={val:-2, sx:{val:19, sx:{val:8}, dx:{val:7, sx:{val:9} } }, dx:{val:-3, sx:{val:-8},dx:{val:7}}}
Dopo la chiamata a tagliaAlberi(t), t contiene {}
t={val:20, sx:{val:19, sx:{val:-8}, dx:{val:7, sx:{val:2} } }, dx:{val:3, sx:{val:-8},dx:{val:1}}};
Dopo la chiamata a tagliaAlberi(t), t contiene {val:20, sx:{val:19, sx:{}, dx:{val:7, sx:{val:2} } }, dx:{val:3, sx:{},dx:{val:1}}}
PS: Viene eliminato il contenuto, non il nodo: quindi resta un { }.
function tagliaAlberi(T) {
let found_sx = false;
let found_dx = false;
if (T === undefined)
return;
if (T.val < 0) {
delete T.sx;
delete T.dx;
delete T.val;
return;
}
if (T.sx && T.sx.val < 0) {
tagliaAlberi(T.sx)
found_sx = true;
}
if (T.dx && T.dx.val < 0) {
tagliaAlberi(T.dx)
found_dx = true;
}
if (!found_sx && !found_dx) {
tagliaAlberi(T.sx)
tagliaAlberi(T.dx)
} else if (!found_sx) {
tagliaAlberi(T.sx)
} else if (!found_dx) {
tagliaAlberi(T.dx)
}
}
Esercizio 20
Si scriva una funzione sonoPari(f) che prende come parametro una funzione f che, dato come argomento un intero, restituisce un valore numerico. sonoPari(f) restituisce una funzione isp(a) che, preso come argomento un array a di valori numerici, restituisce un array di valori booleani res tale che res[i] è true se f(a[i]) è pari, e false altrimenti.
Esempi:
sonoPari(x=>2*x)([1,2,4]) → [true,true,true]
sonoPari(x=>Math.sqrt(x))([1,2,4]) → [false,false,true]
function sonoPari(f) {
return function isp(a) {
return a.map((elem) => f(elem) % 2 == 0);
}
}
Esercizio 21
Si scriva una funzione sommaF(f) che prende come parametro una funzione f che preso un intero restituisce un valore numerico. sommaF(f) restituisce una funzione che prende come parametro un array di interi, e restituisce la somma dei valori restituiti da f su ogni elemento dell’array.
Esempi:
sommaF(x=>x*x)([1,2,3,4]) → 30
sommaF(x=>2*x)([1,2,3,4]) → 20
sommaF(Math.sqrt)([1,2,3,4]) → 6.146264369941973
function sommaF(f) {
return function(a) {
return a.map(f).reduce((acc,curr) => acc + curr,0)
}
}
// oppure
function sommaF(f) {
return function(a) {
let sum = 0;
for (let elem of a)
sum += f(elem)
return sum;
}
}
Esercizio 22
Un anno di dice bisestile se è divisibile per 400, oppure se è divisibile per 4 e non per 100.
Si scriva una funzione contaBisestile(y1,y2), con y1 e y2 due interi positivi che rappresentano anni, con y1 <= y2, restituisce il numero di anni bisestili nell’intervallo [y1, y2].
Esempio:
contaBisestile(2020,2020) → 1
contaBisestile(1904,1908) → 2
contaBisestile(2049,2051) → 0
contaBisestile(0,2020) → 491
function contaBisestile(y1,y2) {
let count = 0;
for (let i = y1; i <= y2; i++) {
if (i % 400 == 0)
count++;
else if (i % 4 == 0 && !(i % 100 == 0))
count++;
}
return count;
}
Esercizio 23
In matematica, un numero vampiro è un numero naturale v>0 costituito da un numero pari di cifre n, tale che v = xy, e x e y sono due naturali ognuno aventi n/2 cifre, che non abbiano entrambi zeri finali, e tali che v contenga esattamente tutte le cifre contenute in x e y. Ad esempio: 1260 è un numero vampiro, perché 1260=21 * 60.
125460 è un numero vampiro perché 125460 = 204 * 615 (o anche perché 125460 = 246*510)
Si scriva una funzione isVampire(v) che, preso come argomento un valore naturale positivo v, restituisca il valore booleano true se v è un vampire number, e false altrimenti. SUGGERIMENTO: si utilizzi il metodo s.slice(i,j) delle stringhe, che, data una stringa s, restituisce la sottostringa di s tra l’indice i (incluso) e j (escluso).
Esempio:
isVampire(1260) → true
isVampire(10) → false
Soluzione proposta da 1boch1
function permutation(num)
{
if(num == "") return [];
let digits = num.split('');
let perms = [];
for(let i = 0; i < digits.length; i++)
{
let app = num.length > 2 ? permutation(num.slice(0, i) + num.slice(i + 1)) : [num.slice(0, i) + num.slice(i + 1)];
for(let j = 0; j < app.length; j++)
{
perms.push(digits[i] + app[j]);
}
}
return perms;
}
function isVampire(n)
{
if(n <= 0) return false;
let num = n.toString();
if(num.length % 2 != 0) return false;
let semiLen = num.length / 2;
let perms = permutation(num);
for(let perm of perms)
{
if(Number(perm.substring(0, semiLen)) * Number(perm.substring(semiLen)) == n && (perm.substring(semiLen - 1, semiLen) != "0" || perm.substring(perm.length - 1) != "0")) return true;
}
return false;
}
Esercizio 24
Si consideri il problema di dover prioritizzare l’ordine di atterraggio degli aerei sulla base del loro carburante residuo. Un singolo aereo è rappresentato dalla proprietà (coppia chiave-valore) {iata:fuel}, dove iata è una stringa che rappresenta il codice univoco del volo e fuel è un valore numerico >= 0 che rappresenta il carburante residuo.
Si scriva la funzione torreDiControllo(aerei), dove aerei è un array (non-ordinato) di aerei. La funzione deve ordinare gli elementi dell’array aerei in ordine crescente di fuel (ovvero dal valore più piccolo al più grande). Si noti che il riordinamento deve necessariamente essere effettuato sul solo array aerei, senza l’utilizzo di ulteriori array di appoggio. La funzione non deve restituire nulla (no return).
Esempi:
aerei = [{AZ100: 56},{LH100: 0.9},{FR99: 12},{AZ800: 7}] dopo la chiamata a torreDiControllo(aerei), aerei contiene [{LH100: 0.9},{AZ800: 7},{FR99: 12},{AZ100: 56}]
function torreDiControllo(aerei) {
function compare(a1,a2) {
let carb_a1 = Object.values(a1)[0];
let carb_a2 = Object.values(a2)[0];
if (carb_a1 < carb_a2)
return -1;
if (carb_a2 < carb_a1)
return 1;
return 0;
// oppure semplicemente carb_a1 - carb_a2
}
return aerei.sort(compare)
}