Esercizio 1. Un gruppo di appassionati di giochi di ruolo dispone di un numero considerevole di dadi (che possiamo considerare illimitato). I dadi sono di vario tipo: da 4 facce, da 5 facce, da 6 facce e, in generale, da k facce, dove k è un qualsiasi intero nell'intervallo [4, 20]. I dadi sono tutti regolari, ovvero ogni faccia di un dado da k facce esce con frequenza 1/k. Il gruppo inventa un gioco. Dato un insieme di n dadi (n>0) da k facce, lanciarli ripetutamente finché almeno metà delle possibili facce sono visibili sul tavolo. Si noti che tutti i dadi devono essere lanciati (non è possibile mantenerne alcuni sul tavolo). Vince il giocatore che raggiunge la sopracitata condizione nel minor numero di lanci. Ad esempio, per n=4 e k=4, se i dadi assumono le facce 2, 2, 4, 4 il giocatore deve riprovare. Se invece le facce assunte dai dadi sono 2, 4, 3, 4 il giocatore può fermarsi.
Modellare la classe InsiemeDadi per consentire al gruppo di cimentarsi nel gioco, avendo cura di implementare almeno i seguenti metodi.
· private InsiemeDadi(int n, int k): un costruttore privato con due parametri (dal significato intuitivo);
· public static InsiemeDadi leggi(Scanner input): un metodo statico che legge da standard input i parametri n e k e costruisce un'istanza di InsiemeDadi;
· public int gioca(): un metodo che esegue il lancio dei dadi finché la condizione target non è raggiunta; il metodo deve restituire il numero di lanci eseguiti.
Modellare e implementare ogni altra classe o metodo che si ritiene utile ai fini dell'esercizio.
SOLUZIONE
//// file Dado.java ////////////////////////////////////////////////////////////////////////////
import java.util.Random;
public class Dado {
private int numeroFacce;
private int valore;
private static Random random = new Random();
public Dado(int numeroFacce) {
if(4 <= numeroFacce && numeroFacce <= 20)
this.numeroFacce = numeroFacce;
else
this.numeroFacce = 6;
lancia();
}
public int getNumeroFacce() {
return numeroFacce;
}
public int getValore() {
return valore;
}
public void lancia() {
valore = random.nextInt(numeroFacce) + 1;
}
}
//// fine file Dado.java ////////////////////////////////////////////////////////////////////
//// file InsiemeDadi.java /////////////////////////////////////////////////////////////////
import java.util.Scanner;
public class InsiemeDadi {
private Dado[] dadi;
public static InsiemeDadi leggi(Scanner input) {
System.out.print("Inserire il numero dei dadi... ");
int n = input.nextInt();
System.out.print("Inserire il numero di facce per ciascun dado... ");
int k = input.nextInt();
return new InsiemeDadi(n, k);
}
private InsiemeDadi(int n, int k) {
dadi = new Dado[n];
for (int i = 0; i < n; i++) {
dadi[i] = new Dado(k);
}
}
public int gioca() {
int numeroLanci = 0;
int count;
do {
numeroLanci++;
System.out.println("Tentativo " + numeroLanci + "... " );
System.out.print(" ");
for (int i = 0; i < dadi.length; i++) {
dadi[i].lancia();
System.out.print(" " + dadi[i].getValore() + " - ");
}
System.out.println();
count = 0;
for (int i = 1; i <= dadi[0].getNumeroFacce(); i++) {
boolean trovato = false;
for (int j = 0; j < dadi.length && !trovato; j++) {
if (dadi[j].getValore() == i) {
count++;
trovato = true;
}
}
}
System.out.println(" valori diversi estratti: " + count);
} while (count <= dadi[0].getNumeroFacce()/ 2);
return numeroLanci;
}
}//// fine file InsiemeDadi.java ///////////////////////////////////////////////////////////////
//// file Main.java ///////////////////////////////////////////////////////////////////////////
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
InsiemeDadi pd = InsiemeDadi.leggi(input);
System.out.println("Punteggio (pari al numero di lanci effettuati): " + pd.gioca());
}
}//// fine file Main.java ///////////////////////////////////////////////////////////////////////
Esercizio 2. É data la seguente classe Java.
public class InterpretazioneCodice {
public static void f(int v[ ], int dim) {
if ( dim > 0 ) {
for ( int i=0; i<dim; i++ )
v[i]--;
f(v, --dim);
}
}
public static void main(String[ ] args) {
int[ ] v = {1,12,5,8,13,-1,4,9,3,6};
f(v, v.length);
for(int i = 0; i < v.length; i++)
System.out.println(v[i]);
}
}
Si svolgano i seguenti punti.
a) Indicare cosa verrà stampato in output dal “main()” (cioè: indicare qual è il contenuto dell’array “v” alla fine dell’esecuzione del programma).
b) Fornire una descrizione del comportamento del metodo “f()”.
SOLUZIONE
a) Alla fine v conterrà -9,3,-3,1,7,-6,0,6,1,5.
b) Il metodo f(), dato il vettore v di dimensione dim, decrementa i valori di v nel seguente modo:
v[i] = v[i] – dim + i --- con 0 <= i < dim
In altre parole, decrementa il primo elemento di una quantità pari a “dim”, il secondo di una pari a “dim-1”, e così via.
9 |
7 |
1 |
8 |
0 |
1 |
3 |
9 |
5 |
0 |
3 |
1 |
6 |
6 |
0 |
2 |
1 |
2 |
7 |
9 |
2 |
0 |
3 |
2 |
Esercizio 3. Si progetti e si implementi in Java un metodo “booleano” che restituisca “true” se è verificato quanto descritto di seguito, e restituisca “false” altrimenti. Il metodo riceve come parametro una matrice di numeri interi di dimensione n*m; si attende in essa una “striscia” di demarcazione che la separa in due parti. Questa “striscia” risulta costituita da elementi “vicini” pari a “0”; essa consente di individuare una regione sinistra ed una regione destra, nella matrice stessa. Si noti che per elementi “vicini” si intendono due elementi presenti in due righe consecutive e su colonne che differiscono al più di uno (quindi sulla stessa colonna oppure su due colonne adiacenti). Si definiscono le due grandezze SOMMA e PRODOTTO come segue: SOMMA è pari alla somma di tutti gli elementi presenti nella regione sinistra della matrice, mentre PRODOTTO è pari al prodotto di tutti gli elementi presenti nella regione destra. Il metodo richiesto dall’esercizio deve restituire “true” se e solo se SOMMA = PRODOTTO. NOTA: sia la regione sinistra che quella destra contengono ALMENO un elemento per ciascuna riga (questo vuol dire che gli zeri non possono mai trovarsi sulla prima colonna, né sull’ultima). ESEMPIO: nella matrice riportata in figura, la somma degli elementi nella regione sinistra è pari a 72, così come il prodotto degli elementi nella regione destra. Il metodo dovrebbe pertanto restituire “true”.
SOLUZIONE
import java.util.*;
public class MatriceDivisaInDue {
public static boolean verificaMatrice(int m [][]) {
int somma = 0, prodotto = 1;
for (int i=0; i<m.length; i++) {
boolean sonoInParteSinistra=true;
for (int j=0; j<m[0].length; j++) {
if (m[i][j] != 0)
if(sonoInParteSinistra) {
System.out.print(m[i][j] + " ");
somma+=m[i][j];
}
else {
System.out.print(m[i][j] + " ");
prodotto = prodotto * m[i][j];
}
else {
sonoInParteSinistra=false;
System.out.print(" || ");
}
}
System.out.println();
}
System.out.println("Somma a sinistra = " + somma +
" // Prodotto a destra = " + prodotto);
return (somma==prodotto);
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Inserire il numero di righe della matrice... ");
int m=input.nextInt();
System.out.print("Inserire il numero di colonne della matrice... ");
int n=input.nextInt();
int matrice[][] = new int [m][n];
System.out.println("Inserire gli elementi della matrice... ");
for (int i=0; i<matrice.length; i++)
for (int j=0; j<matrice[0].length; j++)
matrice[i][j]=input.nextInt();
String esito;
if (verificaMatrice(matrice))
esito="OK!!";
else
esito="NO...";
System.out.println(esito);
}
}