Esercitazione Masterchef

di il
6 risposte

Esercitazione Masterchef

Un cuoco maldestro apre nella sua cucina il barattolo del pepe dalla parte sbagliata. Cadono a terra N
granelli di pepe, da considerare nel seguito come punti materiali.
Il pavimento della cucina è composto di mattonelle quadrate di lato L = 0.5 m e il cuoco si trova all’origine
di un sistema cartesiano (x, y). Ogni mattonella è definita da due punti P1 e P2 che sono le coordinate
degli estremi della diagonale che va dal punto in basso a sinistra a quello in alto a destra, tutte le
coordinate sono in metri ; la mattonella A ha P1 = (0,0) e P2 = (0.5,0.5); la mattonella B ha P1 = (0, 0.5) e P2
= (0.5, 1.0); la mattonella C ha P1 = (0.5,0.5) e P2 = (1.0, 1.0).
I grani di pepe si dispongono in modo casuale sul pavimento, in modo uniforme all’interno di un cerchio
di raggio R = 0.77 m centrato sull’origine (0,0).
Scrivere un programma che simula la posizione dei grani di pepe e calcola il numero di grani caduti nelle
tre mattonelle A, B , e C.
Il programma in particolare deve :
1. Stampare una breve descrizione (una riga) di cosa fa.
2. Chiedere all’utente di inserire il valore intero N di numero di grani di pepe caduti, con
330 = N = 550. Se N non rispetta le condizioni indicate, si deve stampare un messaggio di
errore e richiedere il dato finché non valido
3. Chiamare una funzione genCirc che genera la posizione (x, y) di un grano di pepe
uniformemente in un cerchio di raggio R. A tal fine generare le due coordinate tra -R ed R,
accettandole solo se sqrt(x^2 + y^2) < R, ritirando ad oltranza altrimenti.
4. Chiamare una funzione contaPepe che ricevendo in input la posizione di un grano di pepe
aggiorna il numero di grani nelle mattonelle A, B, C
5. Ripetere i punti 3-4 N volte in modo da contare il numero di granelli caduti nelle 3 mattonelle
6. Ripetere i punti 3-5 100 volte, memorizzando i risultati in 3 array A, B, C
7. Al termine delle 100 ripetizioni, chiamando una opportuna funziona media, calcolare il valore
medio NA, NB, e NC di grani per ciascuna delle 3 mattonelle
8. Stampare (nella funzione main) i tre valori medi sullo schermo in modo chiaro
9. Modificare il main in modo che il parametro R possa venir passato da riga di comando. Il default
deve comunque essere R=0.77.
A me sembra di averlo fatto bene, però quando mi faccio stampare i valori degli array questi hanno tutti 0 come valore (a volte anche 1), e dunque la media risulta falsata, come mai?

Mio svolgimento
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define R 0.77
double distanza (double x , double y);
void genCirc (double *x, double *y, double radius);
void contaPepe(double x, double y,int cca, int ccb, int cc,int *countA, int *countB, int *countC);
double media (int x[], int size, int a);
int main()
{
  int N;
  srand(time(NULL));  
  do
    {
      printf("Inserisci un numero intero tra 330 e 550\n");
      scanf("%d",&N);
      if (N < 330 || N > 550)
        {
          printf("ERRORE!\n");   
        }
    }
  while (N < 330 || N > 550);  
  int i, countA, countB, countC, k, A[100], B[100], C[100];
  double x, y;
  for (k=0; k<100; k++)
  {
    countA=0;
    countB=0;
    countC=0;  
    for (i=0; i<N; i++)
      {
        genCirc (&x, &y, R);
        contaPepe(x,y,countA,countB,countC,&countA, &countB, &countC);
      }
     A[k] = countA;
     B[k] = countB;
     C[k] = countC; 
  }
  printf("La media dei grani trovati delle mattonelle A,B,C vale rispettivamente: %lf %lf %lf\n",media(A,100,100), media(B,100,100), media(C,100,100));
}

double distanza (double x , double y)
{
  return sqrt(x*x + y*y);
}

void genCirc (double *x, double *y, double radius)
{
  double a,b;  
  do
    {
      a = (2*radius) * ( (double)rand() / (double)RAND_MAX ) - radius;
      b = (2*radius) * ( (double)rand() / (double)RAND_MAX ) - radius;  
    }
  while (distanza(a,b) < radius); 
  *x = a;
  *y = b;   

}

void contaPepe(double x, double y,int cca, int ccb, int ccc,int *countA, int *countB, int *countC)
{
  cca=0, ccb=0, ccc=0;  
  if (x>= 0.0 && x<= 0.5 && y >= 0 && y <= 0.5)
    {
      cca++;  
    }
   if (x>= 0.0 && x<= 0.5 && y >= 0.5 && y <= 1.0)
    {
      ccb++;  
    }
  if (x>= 0.5 && x<= 1 && y >= 0.5 && y <= 1.0)
    {
      ccc++;  
    } 
   *countA = cca;
   *countB = ccb;
   *countC = ccc; 
}
double media (int x[], int size, int a)
{
  int i;
  double sum=0;
  for (i=0; i<size; i++)
    {
      sum += x[i];   
    }
  return sum/a;  
}

6 Risposte

  • Re: Esercitazione Masterchef

    
       *countA = cca;
       *countB = ccb;
       *countC = ccc; 
    
    Quindi o zero o uno...
  • Re: Esercitazione Masterchef

    
    void contaPepe(double x, double y, int *countA, int *countB, int *countC)
    {
      if (x >= 0.0 && x < 0.5 && y >= 0.0 && y < 0.5)
        *countA = *countA + 1;
      if (x >= 0.0 && x < 0.5 && y >= 0.5 && y < 1.0)
        *countB = *countB + 1;
      if (x >= 0.5 && x < 1.0 && y >= 0.5 && y < 1.0)
        *countC = *countC + 1; 
    }
    
  • Re: Esercitazione Masterchef

    A continua ad avere come valori tutti 0, mentre B e C hanno valori tipici di array non inizializzati
  • Re: Esercitazione Masterchef

    Dracmaleontes ha scritto:


    A continua ad avere come valori tutti 0, mentre B e C hanno valori tipici di array non inizializzati
    E certo, se fai le condizioni al contrario...
    while (distanza(a,b) > radius); 
    anzi meglio
    while (a*a + b*b > radius*radius); 
  • Re: Esercitazione Masterchef

    Perfetto, grazie ora funziona, ma ponendo la condizione in questo modo non vengono presi i punti al di fuori della circonferenza?
  • Re: Esercitazione Masterchef

    No, vengono presi i punti dentro la circonferenza. Ripassa il do while
Devi accedere o registrarti per scrivere nel forum
6 risposte