/*** 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 10    /// 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[])
{
    /**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;
    for(i=0; i < MAX; i++)
        if(ce(v2,v1[i],MAX))  /// Se v1[i] c'e' in v2 ...
            if(!ce(v3,v1[i],k)) /// Se v1[i] NON c'e' in v3[3] ....
                v3[k++]=v1[i];    /// lo aggiungo in v3
    printf("\nEs2A) Elementi comuni ai due vettori:\n");
    visualizza(v3,k);  /// k mi dice quanti sono i valori di v3
}

void es2B(int v1[], int v2[])
{
    /*** 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] ***/
    int k=0;
    int v3[MAX];
    int i;
    int el; /// elementi cercati

    for(i=0; i < MAX; i++) /// metto in v3 gli elementi comuni di v1 e v2
        if(ce(v2,v1[i],MAX))
            if(!ce(v3,v1[i],k)) /// lo metto in v3 SOLO se non c'e' gia'
                v3[k++]=v1[i];
    /// ora in v3 ci sono i K elementi comuni ai due vettori
    printf("\nES2B) 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
    {
        el=v1[i];
        if (!ce(v3,el,k)) printf("E' solo in v1[]: %d\n",el);  /// se el non e' nei comuni lo stampo
        el=v2[i];
        if (!ce(v3,el,k)) printf("E' solo in v2[]: %d\n",el);  /// se el non e' nei comuni lo stampo
    }
}


void es3A()
{
    /** 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=0,j=0,seq;

    do
    {

        elem=bin[i];
        seq=1;    /// lunghezza della attuale sequenza
        while(bin[i]==bin[i+1] && i < ELEM-1)
            i++,seq++;
        sequenza[j]=seq;
        j++;
        i++;
    }
    while(i < ELEM);
    printf("\nEs3A) Ecco le sequenza di bin[]:\n");
    visualizza(sequenza,j);
}


void es3B()
{
    /*** 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("\nEs3B) 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()
{
    /*** 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) Numero generato=%d\n",num);


    for(i=0; i <6; i++)   /// le cifre sono sempre 6
    {
        cifra=num % 10;
        if (cifra%2==0) /// se la cifra e' pari
            v[j++]=cifra; /// la metto nel vettore
        num/=10;

    }
    printf("Ecco le %d cifre pari nel vettore:\n",j);
    visualizza(v,j);

}

int massimo(int v[], int nelem) /// ritona 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 == 1) s1=1;   /// lunghezza della attuale sequenza di 1
        else s0=1;    /// lunghezza della attuale sequenza di 0

        while(elem==1 && bin[i]==bin[i+1] && i < ELEM-1) /// vedo se e' una sequenza di 1
            i++,s1++;
        while(elem==0 && bin[i]==bin[i+1] && i < ELEM-1) /// o vedo se e' una sequenza di 0
            i++,s0++;
        if (elem==1) seq1[j1++]=s1; /// metto opportunamente la lunghezza della sequenza nel suo vettore
        else seq0[j0++]=s0;
        i++;
    }
    while(i < ELEM);
    printf("\nEs4B)\n");
    printf("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()
{
/*** 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]
diventa
[10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
***/
 int v[] = {2,4,6,8,10,12,14,16,18,20};
    int dep,i;
    int elem=sizeof(v)/sizeof(int); /// cosi puoi allungare a piacere il vettore

    dep=v[0];  //// metto in dep il primo elemento del vettore
    for(i=0; i < elem-1; i++)
        v[i]=v[i+1];
    v[elem-1]=dep;
    printf("\nEs5A) shift a destra :\n");
    visualizza(v,elem);  /// visualizzo il vettore
}

void es5B()
{
    /*** 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); /// cosi puoi allungare a piacere il vettore

    dep=v[elem-1];  //// metto in dep l'ultimo elemento del vettore
    for(i=elem-1; i >0; i--)
        v[i]=v[i-1];
    v[0]=dep;
    printf("\nEs5B) shift a sinistra:\n");
    visualizza(v,elem);  /// visualizzo il vettore
}




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 così 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;
}


