/*** verifica Febbraio C: soluzioni di tutti gli esercizi (Fila A e B)
     NB: gli esercizi 1A e 1B sono risolti direttamente nel main(), per gli altri otto,
     sono state codificate otto funzioni e poi sono state richiamate dal main
***/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 5   /// dimensione dei vettori

// Random(X) ritorna un numero fra 1 e X

int Random(int N)
{
    static int primavolta = 1; // BOOLEANO
    if (primavolta)
    {
        srand(time(NULL)); /* inizializzo il seme */
        primavolta = 0;
    }
    return (rand() % N) + 1;
}


/// visualizza un vettore in verticale
void visualizza(int v[], int nelem)
{
    int i;
    for(i=0; i < nelem; i++)
    {
        printf("v[%d]=%d\n",i,v[i]);
    }
}

/// Funzione utilissima per molti esercizi proposti
int ce(int v[], int elem, int dim)
/// verifica se in un vettore di dimensione dim, c'e' l'elemento elem
{
    int i;
    for(i=0; i < dim; i++)
        if(v[i]==elem) return 1; // vero, elem e' nel vettore
    return 0; /// falso, elem non c'e' nel vettore
}

void es2A(int v1[], int v2[]) //Buonocore
{
    /**Scrivi un programma che, acquisiti due vettori di 10 elementi interi,
    vet1 e vet2, crei e stampi un terzo vettore che contenga gli elementi
    che sono presenti in entrambi gli array. [punti 2]  **/
    int k = 0;
    int v3[MAX];
    int i;

    printf("\n----------\n");
    printf("   Es2A Buonocore\n");
    printf("----------\n");

    for(i = 0; i < MAX; i++)
        if(ce(v2, v1[i], MAX))
            if(!ce(v3, v1[i], k+1))
                v3[k] = v1[i], k++;

    printf("Elementi comuni ai due vettori:\n");

    visualizza(v3,k);  /// k mi dice quanti sono i valori di v3
}



void es2B(int v1[], int v2[]) //Buonocore
{
    /*** Scrivi un programma che, acquisiti due vettori di 10 elementi interi,
    vet1 e vet2, crei e stampi un terzo vettore che contenga gli
    elementi che NON sono presenti in entrambi gli array. [punti 2] ***/
    printf("\n----------\n");
    printf("   Es2B Buonocore\n");
    printf("----------\n");

    int k=0;
    int v3[MAX];
    int i;
    int el; /// elementi cercati

    /// ora in v3 ci sono i K elementi comuni ai due vettori
    printf("Elementi che ci sono solo nel primo o solo nel secondo vettore:\n");
    for(i=0; i < MAX; i++)  /// cerco in v1 e poi in v2
        if(!ce(v2, v1[i], MAX))
            if(!ce(v3, v1[i], k+1))
                v3[k] = v1[i], k++;

    for(i=0; i < MAX; i++)  /// cerco in v1 e poi in v2
        if(!ce(v1, v2[i], MAX))
            if(!ce(v3, v2[i], k+1))
                v3[k] = v2[i], k++;

    visualizza(v3, k);
}

void es3A() /// buonocore
{
    /** Realizzare un programma che, inserita in un array una sequenza di 1 e 0, crei un altro array (l’array
    sequenza) che contenga la lunghezza delle sequenze di zeri e uni presenti nel primo array. [punti 2.25]
    int bin[]={1,1,1,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0} →
    sequenza=[3,2,4,3,2,4] **/

    int bin[]= {1,1,1,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0};
    int sequenza[sizeof(bin)/sizeof(int)]; /// cosi puoi cambiare a piacere il vettore sopra
    int elem; /// elemento che sto esaminando
    int ELEM=sizeof(bin)/sizeof(int); /// dimensione del vettore bin
    int i = 1,j = 1,seq = 0;



    do
    {
        if(bin[i-1] == bin[i])
            j++;
        else
            sequenza[seq] = j, seq++, j = 1;
        i++;
    }
    while(i <= ELEM);

    sequenza[seq] = j;

    printf("\n3A) (Buonocore) Ecco le sequenza di bin[]:\n");
    printf("bin[]= {1,1,1,0,0,1,1,1,1,0,0,0,1,1,0,0,0,0};\n");
    visualizza(sequenza,seq);
}


void es3B() /// Buonocore
{
    /*** Esercizio 3B
    Dato un numero di 6 cifre generato casualmente, realizza un programma che generi un array con le singole
    cifre del numero in ordine inverso [punti 2]
    Es.
    348597 -> [7, 9, 5, 8, 4, 3] **/

    int num;
    int v[6];
    int i;
    num=100000; /// numero minimo di 6 cifre
    num+=Random(900000)-1; /// genero fra 0 e 899999

    printf("\n3B) (Buonocore) Numero generato=%d\n",num);

    for(i = 0; i < 6; i++)   /// le cifre sono sempre 6
        v[i] = num % 10, num /= 10;

    printf("Ecco le cifre nel vettore:\n");
    visualizza(v,6);


}


/*****/
void es4A() //// Di Gangi
{
    /*** Scrivi un programma in C che, dato un numero intero positivo di 6 cifre generato casualmente, trovi le sue
    cifre pari e le salvi, rovesciate, in un array. Se non ci sono cifre pari, l'array dovrÃ  contenere tutti 0. [punti 2]
    Es.
    347268
    risulta
    [8, 6, 2, 4] ***/

    int num;
    int v[6]= {0}; /// vettore azzerato
    int i,j;
    int cifra;

    num=100000; /// numero minimo di 6 cifre
    num+=Random(900000)-1; /// genero fra 0 e 899999
    printf("\nEs 4A) (Di Gangi) Numero generato=%d\n",num);
    for(i = 0; i < 6; i++)
    {
        cifra = num % 10;
        if(cifra % 2 == 0)
        {
            v[j] = cifra;
            j++;
        }
        num /= 10;
    }

    if(j == 0)
    {
        for(i = 0; i < 6; i++) v[i] = 0;
        j = 6;
    }
    printf("Ecco le %d cifre pari nel vettore:\n",j);
    visualizza(v,j);

}





int massimo(int v[], int nelem) /// ritorna il massimo di un vettore
{
    int i;
    int max=v[0];
    for(i=1; i < nelem; i++)
        if (v[i]> max) max=v[i];
    return max;
}



void es4B() /// Si puo' fare una variante della soluzione qui sotto: usare un solo vettore per le sequenze
/// numerando le sequenze di 1 con valori positivi e quelle di 0 con valori negativi.
{
    /*** Esercizio 4
    Realizzare un programma in linguaggio C che, inserita in un array una sequenza di 0 e 1, determini la
    lunghezza massima della sequenza di zeri consecutivi e la lunghezza massima della sequenza di uni
    consecutivi presenti nell'array. [punti 2.25]
    int bin[]={1,1,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0}
    max 1 = 4
    max 0 = 5
    ***/
    int bin[]= {1,1,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0};
    int ELEM=sizeof(bin)/sizeof(int);
    int elem; /// elemento che sto esaminando
    int i=0,j0, j1, s0, s1;
    int seq1[ELEM/2];  /// sequenze di 1
    int seq0[ELEM/2];  /// sequenze di 0
    j0=j1=0; /// indici dei 2 vettori seq0 e seq1
    s0=s1=0; /// s0==lunghezza sequenze di 0, s1 == lunghezza di seq. di 1
    do
    {

        elem=bin[i]; /// prendo il prox elemento;
        if(elem == 0)
        {
            s0++;          // aumento la lunghezza della sequenza di 0
            if(s1 > 0)     // se prima stavo contando 1
            {
                seq1[j1++] = s1;  // salvo la sequenza di 1
                s1 = 0;           // resetto il contatore di 1
            }
        }
        else // elem == 1
        {
            s1++;          // aumento la lunghezza della sequenza di 1
            if(s0 > 0)     // se prima stavo contando 0
            {
                seq0[j0++] = s0;  // salvo la sequenza di 0
                s0 = 0;           // resetto il contatore di 0
            }
        }
        i++;
    }
    while(i<ELEM);

    if(s0 > 0)
        seq0[j0++] = s0;
    if(s1 > 0)
        seq1[j1++] = s1;

    while(i < ELEM);
    printf("\nEs4B)\n");
    printf("int bin[]= {1,1,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0};\n");
    printf("Sequenze di 0:\n");
    visualizza(seq0,j0);
    printf("Sequenze di 1:\n");
    visualizza(seq1,j1);
    printf("La lunghezza massima di zeri e' %d\n",massimo(seq0,j0));
    printf("La lunghezza massima di uni  e' %d\n",massimo(seq1,j1));
}



void es5A()  //// Talunkdar
{
    /*** Dato un array di 10 elementi interi, realizzare un programma
    che effettui lo shift di una posizione a destra
    dei valori dell'array. L'ultimo elemento si shifta col primo.
    Al termine si dovrÃ  stampare l'array modificato. [punti 2.25]
    Es.
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      ***/
    int v[] = {2,4,6,8,10,12,14,16,18,20};
    int dep,i;
    int elem = sizeof(v)/sizeof(int);

    dep = v[elem-1];

    for(i = elem-1; i > 0; i--)
    {
        v[i] = v[i-1];
    }

    v[0] = dep;

    printf("\nShift a destra (Talunkdar):\n");
    visualizza(v,elem);
}



void es5B() /// Di Gangi
{
    /*** Dato un array di 10 elementi interi, realizzare un programma che effettui lo shift di una posizione a sinistra
    dei valori dell'array. Il primo elemento si shifta con lâ€™ultimo. [punti 2.25]
    Al termine si dovrÃ  stampare l'array modificato.
    Es.
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    diventa
    [2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
    ***/
    int v[] = {2,4,6,8,10,12,14,16,18,20};
    int dep,i;
    int elem=sizeof(v)/sizeof(int);
    printf("\nEs5B) shift a sinistra(Di Gangi):\n");
    printf("Array originale: \n");
    visualizza(v, elem);

    int temp = v[0];

    for(int i = 0; i < elem-1; i++) {
        v[i] = v[i+1];
    }
    v[elem-1] = temp;

    printf("\nEs5B) shift a sinistra:\n");
    visualizza(v,elem);
}



int main()
{
    int v1[MAX], v2[MAX];
    int i;
    int somma=0;
    for(i=0; i < MAX; i++ ) /// riempio 2 vettori
    {
        v1[i]=Random(20);
        v2[i]=Random(20);
    }
    visualizza(v1,MAX);
    printf("----------------------------\n");
    visualizza(v2,MAX);

    /***Scrivere un programma in C che calcola il prodotto scalare di due vettori di 7 numeri
    ciascuno generati casualmente tra 1-10.]
    (“Per ottenere il prodotto scalare si moltiplicano gli elementi che stanno nella stessa
    posizione nei due array e poi si sommano tutti i prodotti ottenuti.”) [punti 1.5] ***/


    for(i=0; i < MAX; i++)
        somma+= v1[i]*v2[i]; /// ***
    printf("Prodotto scalare FILA A= %d\n",somma);

    /**
    Scrivere un programma in C che calcoli la somma dei prodotti incrociati
    di due vettori di 7 numeri ciascuno generati casualmente tra 1-10.
    Il prodotto incrociato si calcola moltiplicando il primo
    elemento del primo vettore con l'ultimo elemento del secondo vettore,
    il secondo con il penultimo, e cosi' via.
    Il programma deve stampare i due vettori e il risultato finale. [punti 1.5] **/

    somma=0;
    for(i=0; i < MAX; i++)
        somma+= v1[i]*v2[MAX-1-i]; /// ***
    printf("Prodotto scalare FILA B= %d\n",somma);

    es2A(v1,v2);

    es2B(v1,v2);

    es3A();

    es3B();

    es4A();

    es4B();

    es5A();

    es5B();

    return 0;
}


