Progetto di informatica

di il
73 risposte

73 Risposte - Pagina 3

  • Re: Progetto di informatica

    Dal momento che mi sono cimentato nel risolvere l'esercizio, ti posto il codice completo:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    #define N 256
    
    typedef struct nodo_
    {
        char *p;
        char *res;
        uint8_t SI[N];
        uint8_t NO[N];
        uint8_t u[N];
        unsigned int u_dim;
        int flag_comp;
        struct nodo_ *next;
    }   nodo;
    
    nodo* aggiungi_nodo_in_ordine(nodo **ptr, char *p, unsigned int k)
    {
        while(*ptr && strcmp((*ptr)->p, p) < 0)
        {
            ptr = &(*ptr)->next;
        }
        nodo *nuovo = (nodo*)malloc(sizeof(nodo));
        nuovo->p = (char*)malloc(sizeof(char) * (k + 1));
        strcpy(nuovo->p, p);
        nuovo->res = (char*)malloc(sizeof(char) * (k + 1));
        *nuovo->res = nuovo->res[k] = '\0';
        nuovo->next = *ptr;
        return(*ptr = nuovo);
    }
    
    nodo* trova_nodo(nodo *ptr, char *p)
    {
        int cmp = 1;
        while(ptr && (cmp = strcmp(p, ptr->p)) > 0)
        {
            ptr = ptr->next;
        }
        return(!cmp ? ptr : NULL);
    }
    
    void definisci_alfabeto(uint8_t *alf)
    {
        for(char c = '0'; c <= '9'; ++alf[c++]);
        for(char c = 'A'; c <= 'Z'; ++alf[c++]);
        for(char c = 'a'; c <= 'z'; ++alf[c++]);
        ++alf['-'];
        ++alf['_'];
    }
    
    int verifica_parola_valida(char *p, uint8_t *alf, unsigned int k)
    {
        unsigned int i;
        for(i = 0; i < k && alf[p[i]]; ++i);
        return(i == k && !p[i]);
    }
    
    int verifica_parola_ammissibile(nodo **ptr, nodo *p_amm, char *p)
    {
        if(!(*ptr = trova_nodo(p_amm, p)))
        {
            printf("     not_exists\n");
        }
        return(*ptr != NULL);
    }
    
    int verifica_parola_compatibile(char *p2, nodo *nd_p)
    {
        uint8_t v[N] = {0};
        unsigned int i;
        for(i = 0; nd_p->p[i] && (nd_p->res[i] == '+' ? p2[i] == nd_p->p[i] : p2[i] != nd_p->p[i] && ++v[p2[i]] && (!nd_p->NO[p2[i]] || nd_p->SI[p2[i]] - v[p2[i]] >= 0)); ++i);
        for(i = !nd_p->p[i] ? 0 : nd_p->u_dim + 1; i < nd_p->u_dim && v[nd_p->u[i]] - nd_p->SI[nd_p->u[i]] >= 0; ++i);
        return(i == nd_p->u_dim);
    }
    
    void aggiungi_nuove_parole_ammissibili(nodo **p_amm, char *input, uint8_t *alf, unsigned int k, int flag_sequenza_iniziale, unsigned int n, unsigned int *n_p_comp)
    {
        while(1)
        {
            printf("  -> ");
            scanf(" %s", input);
            if(verifica_parola_valida(input, alf, k))
            {
                nodo *ptr = aggiungi_nodo_in_ordine(p_amm, input, k);
                if(n && *n_p_comp)
                {
                    nodo *temp = *p_amm;
                    while(temp && (!*temp->res || (ptr->flag_comp = verifica_parola_compatibile(ptr->p, temp))))
                    {
                        temp = temp->next;
                    }
                    *n_p_comp += !temp;
                }
            }
            else if(flag_sequenza_iniziale ? *p_amm && !strcmp(input, "+nuova_partita") : !strcmp(input, "+inserisci_fine"))
            {
                break;
            }
        }
    }
    
    void nuova_partita(nodo **nd_r, nodo *p_amm, char *input, uint8_t *alf, unsigned int k, unsigned int *n, unsigned int *n_p_comp)
    {
        do
        {
            printf("r -> ");
            scanf(" %s", input);
        }
        while(!verifica_parola_valida(input, alf, k) || !verifica_parola_ammissibile(nd_r, p_amm, input));
        do
        {
            printf("n -> ");
            scanf("%u", n);
        }
        while(!*n);
        while(p_amm)
        {
            *p_amm->res = '\0';
            p_amm->flag_comp = 1;
            p_amm = p_amm->next;
        }
        *n_p_comp = 0;
    }
    
    void stampa_filtrate(nodo *p_amm, unsigned int n_p_comp)
    {
        while(n_p_comp)
        {
            if(p_amm->flag_comp)
            {
                printf("     %s\n", p_amm->p);
                --n_p_comp;
            }
            p_amm = p_amm->next;
        }
    }
    
    void determina_stringa_confronto(char *r, nodo *nd_p)
    {
        memset(nd_p->SI, nd_p->u_dim = 0, sizeof(*nd_p->SI) * N);
        memset(nd_p->NO, 0, sizeof(*nd_p->NO) * N);
        uint8_t v[N] = {0};
        for(unsigned int i = 0; r[i]; ++i)
        {
            if(nd_p->p[i] == r[i])
            {
                nd_p->res[i] = '+';
            }
            else
            {
                nd_p->res[i] = '/';
                ++v[r[i]];
            }
        }
        for(unsigned int i = 0; r[i]; ++i)
        {
            if(nd_p->res[i] == '/')
            {
                if(v[nd_p->p[i]])
                {
                    nd_p->res[i] = '|';
                    --v[nd_p->p[i]];
                    if(!nd_p->SI[nd_p->p[i]]++)
                    {
                        nd_p->u[(nd_p->u_dim)++] = nd_p->p[i];
                    }
                }
                else
                {
                    ++nd_p->NO[nd_p->p[i]];
                }
            }
        }
    }
    
    void determina_parole_compatibili(nodo *p_amm, nodo *nd_r, nodo *nd_p, unsigned int *n_p_comp)
    {
        *n_p_comp = 0;
        while(p_amm)
        {
            if(p_amm == nd_r || p_amm->flag_comp && (p_amm->flag_comp = verifica_parola_compatibile(p_amm->p, nd_p)))
            {
                ++*n_p_comp;
            }
            p_amm = p_amm->next;
        }
    }
    
    int main()
    {
        unsigned int k;
        unsigned int n;
        unsigned int n_p_comp;
        nodo *p_amm = NULL;
        nodo *nd_r;
        nodo *nd_p;
        char input[500];
        uint8_t alf[N] = {0};
        definisci_alfabeto(alf);
        do
        {
            printf("k -> ");
            scanf("%u", &k);
        }
        while(!k);
        aggiungi_nuove_parole_ammissibili(&p_amm, input, alf, k, 1, 0, &n_p_comp);
        nuova_partita(&nd_r, p_amm, input, alf, k, &n, &n_p_comp);
        while(1)
        {
            printf("  -> ");
            scanf(" %s", input);
            if(n && verifica_parola_valida(input, alf, k) && verifica_parola_ammissibile(&nd_p, p_amm, input))
            {
                if(nd_p == nd_r)
                {
                    printf("     ok\n");
                    n = 0;
                }
                else
                {
                    determina_stringa_confronto(nd_r->p, nd_p);
                    determina_parole_compatibili(p_amm, nd_r, nd_p, &n_p_comp);
                    printf("     %s\n     %u\n", nd_p->res, n_p_comp);
                    if(!--n)
                    {
                        printf("     ko\n");
                    }
                }
            }
            else if(n && !strcmp(input, "+stampa_filtrate"))
            {
                stampa_filtrate(p_amm, n_p_comp);
            }
            else if(!strcmp(input, "+inserisci_inizio"))
            {
                aggiungi_nuove_parole_ammissibili(&p_amm, input, alf, k, 0, n, &n_p_comp);
            }
            else if(!strcmp(input, "+nuova_partita"))
            {
                nuova_partita(&nd_r, p_amm, input, alf, k, &n, &n_p_comp);
            }
            else if(!strcmp(input, "+exit"))
            {
                break;
            }
        }
        return 0;
    }
    
    Non l'ho testato più di tanto, ma sembra funzionare... eventualmente puoi trarne qualche spunto.
    Se qualcosa non ti è chiaro o riscontri qualche bug, fammi sapere.


    P.S.
    Ho aggiornato la funzione fun_compatibilita_Nippolo() postata in precedenza, in quanto conteneva un errore.
  • Re: Progetto di informatica

    Tutto chiaro. Cercherò di sfruttare al meglio quello che hai fatto. Ti ringrazio molto
  • Re: Progetto di informatica

    Buongiorno a tutti, purtroppo mi serve ancora il vostro aiuto. Pensavo che il programma scritto da Nippolo sarebbe andato bene, e invece così non è stato. L'output è assolutamente corretto, il problema è il tempo d'esecuzione. L'esito del test è il seguente

    “Esecuzione terminata perché fuori tempo massimo”

    Tempo di esecuzione: 3,086 s

    Memoria utilizzata: 256 KiB

    Come potete immaginare, non so nulla riguardo al test, perciò la cosa si fa critica. Spero che qualcuno di voi abbia ancora un po' di tempo da dedicarmi.

  • Re: Progetto di informatica

    Ma il professore vi ha detto qual è l'ordine di grandezza di dimensione e numero delle righe che dovete maneggiare? Possibile che non ve l'abbia detto, dato che vi mette vincoli temporali?

    Perché da standard input e non da file, questo test? Lo stream dello standard input viene reindirizzato? Come fate a sapere che lo standard input non si sia inchiodato per una delle solite cavolate note che succedono quando si fanno queste cose?

    Perché il professore non mette qualcosa di ragionevole, tipo che termina l'esecuzione dopo 60 secondi invece di 3 e, semplicemente, vi dice che il test è fallito perché è terminato fuori tempo massimo? Così uno si regola se il programma è bloccato su una cavolata oppure su quanto tempo di esecuzione deve recuperare.

    Tutte cose che potete e dovete chiedere direttamente a lui

  • Re: Progetto di informatica

    Non so per quale assurdo motivo, ma non ci è stata data alcuna informazione a riguardo.

    Ovviamente ho provato a chiedere chiarimenti al professore, ma si è rifiutato di rispondere.

  • Re: Progetto di informatica

    Questo è quanto.

  • Re: Progetto di informatica

    L'esito che ho riportato sopra è riferito a un altro test.

    Nell'immagine si trovano i dettagli del test che devo assolutamente superare.

    Scusate se ho frammentato i messaggi.

  • Re: Progetto di informatica

    Ammetto di non ricordare benissimo né lo scopo del programma né il modo in cui l'ho implementato, ma prima di rinfrescarmi la memoria vorrei innanzitutto capire in cosa consiste precisamente questo test.

  • Re: Progetto di informatica

    Non lo so e non mi è dato saperlo. Probabilmente il problema sono le strutture dati. Pensavo di creare tre liste invece che una sola. La prima lista contiene le parole ammissibili, la seconda contiene le parole ammissibili compatibili con i vincoli appresi, mentre la terza contiene le parole che sono state confrontate con i relativi esiti. In questo modo alcune operazioni verrebbero velocizzate, a scapito di una maggiore occupazione di memoria.

  • Re: Progetto di informatica

    Per la prima lista, quella contenente tutte le parole ammissibili, si potrebbe usare un albero binario di ricerca. Per le altre due non credo ci siano problemi ad utilizzare le liste concatenate.

  • Re: Progetto di informatica

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define N 256
    
    typedef struct node_ {
        char *word;
        char *comparison;
        struct node_ *next;
        int Yes[N];
        int No[N];
        int not_equal[N];
        int dimension;
    } node;
    
    typedef struct nodo_ {
        char *word;
        struct nodo_ *next;
    } nodo;
    
    typedef struct tree_node_ {
        char *word;
        struct tree_node_ *left;
        struct tree_node_ *right;
    } tree_node;
    
    void define_alphabet2(int *alp)
    {
        for(char c = '0'; c <= '9'; ++alp[(int)c++]);
        for(char c = 'A'; c <= 'Z'; ++alp[(int)c++]);
        for(char c = 'a'; c <= 'z'; ++alp[(int)c++]);
        ++alp['-'];
        ++alp['_'];
    }
    
    int check_validity2(const char *p, const int *alp, int k)
    {
        unsigned int i;
        for(i = 0; i < k && alp[(int)p[i]]; ++i);
        return(i == k && !p[i]);
    }
    
    node* add_node2(char *i, node **p2, int l) {
        node *new;
    
        new = (node*)malloc(sizeof(node));
        new->word = (char*)malloc(sizeof(char) * (l + 1));
        strcpy(new->word, i);
        new->comparison = (char*)malloc(sizeof(char) * (l + 1));
        new->comparison[l] = '\0';
        new->dimension = 0;
        new->next = *p2;
        *p2 = new;
        return(*p2);
    }
    
    void add_eligible_word(char *i, tree_node **p, int l) {
        if(*p == NULL) {
            *p = (tree_node*)malloc(sizeof(tree_node));
            (*p)->word = (char*)malloc(sizeof(char) * (l + 1));
            strcpy((*p)->word, i);
            (*p)->left = NULL;
            (*p)->right = NULL;
        } else if(strcmp((*p)->word, i) < 0) {
            add_eligible_word(i, &(*p)->right, l);
        } else {
            add_eligible_word(i, &(*p)->left, l);
        }
    }
    
    nodo* add_compatible_word2(char *i, nodo **p1, int l) {
        nodo *new;
    
        while((*p1 != NULL) && (strcmp((*p1)->word, i) <= 0)) {
            p1 = &(*p1)->next;
        }
        new = (nodo*)malloc(sizeof(nodo));
        new->word = (char*)malloc(sizeof(char) * (l + 1));
        strcpy(new->word, i);
        new->next = *p1;
        *p1 = new;
        return(*p1);
    }
    
    int calculate_compatibility2(const char *i, node *p2) {
        int v[N] = {0};
        unsigned int count;
        for(count = 0; p2->word[count] && (p2->comparison[count] == '+' ? i[count] == p2->word[count] : i[count] != p2->word[count] && ++v[(int)i[count]] && (!p2->No[(int)i[count]] || p2->Yes[(int)i[count]] - v[(int)i[count]] >= 0)); ++count);
        for(count = !p2->word[count] ? 0 : p2->dimension + 1; count < p2->dimension && v[p2->not_equal[count]] - p2->Yes[p2->not_equal[count]] >= 0; ++count);
        return(count == p2->dimension);
    }
    
    int calculate_compatibilities2(char *i, node **p2) {
        while(*p2 != NULL) {
            if(calculate_compatibility2(i, *p2) != 1) {
                return(-1);
            }
            p2 = &(*p2)->next;
        }
        return(1);
    }
    
    void add_words2(char *i, tree_node **p, nodo **p1, node **p2, int l, int *alp) {
        while(1) {
            //printf("inserire una nuova parola o il comando +inserisci_fine\n");
            if(scanf("%s", i) == 1) {
                if(strcmp("+inserisci_fine", i) == 0) {
                    break;
                } else {
                    if(check_validity2(i, alp, l) == 1) {
                        add_eligible_word(i, p, l);
                        if(calculate_compatibilities2(i, p2) == 1) {
                            add_compatible_word2(i, p1, l);
                        }
                    }
                }
            }
        }
    }
    
    int find_word2(char *i, tree_node **p) {
        int val;
    
        if(*p != NULL) {
            if((val = strcmp((*p)->word, i)) == 0) {
                return(1);
            } else if(val < 0) {
                return(find_word2(i, &(*p)->right));
            } else {
                return(find_word2(i, &(*p)->left));
            }
        } else {
            return(-1);
        }
    }
    
    void print_filtered_words2(nodo **p1) {
        while(*p1 != NULL) {
            printf("%s\n", (*p1)->word);
            p1 = &(*p1)->next;
        }
    }
    
    void calculate_comparison2(const char *k, node *p2) {
        memset(p2->Yes, p2->dimension = 0, sizeof(*p2->Yes) * N);
        memset(p2->No, 0, sizeof(*p2->No) * N);
        int v[N] = {0};
        for(unsigned int i = 0; k[i]; ++i)
        {
            if(p2->word[i] == k[i])
            {
                p2->comparison[i] = '+';
            }
            else
            {
                p2->comparison[i] = '/';
                ++v[(int)k[i]];
            }
        }
        for(unsigned int i = 0; k[i]; ++i)
        {
            if(p2->comparison[i] == '/')
            {
                if(v[(int)p2->word[i]])
                {
                    p2->comparison[i] = '|';
                    --v[(int)p2->word[i]];
                    if(!p2->Yes[(int)p2->word[i]]++)
                    {
                        p2->not_equal[(p2->dimension)++] = (unsigned char ) p2->word[i];
                    }
                }
                else
                {
                    ++p2->No[(int)p2->word[i]];
                }
            }
        }
    }
    
    int list_length2(nodo **p1) {
        int i = 0;
        while(*p1 != NULL) {
            ++i;
            p1 = &(*p1)->next;
        }
        return(i);
    }
    
    void compare2(nodo **p1, node *p2, char *k) {
        nodo **pp1 = p1;
        nodo *del1;
        calculate_comparison2(k, p2);
        while(*p1 != NULL) {
            if(calculate_compatibility2((*p1)->word, p2) != 1) {
                del1 = *p1;
                *p1 = (*p1)->next;
                free(del1);
            } else {
                p1 = &(*p1)->next;
            }
        }
        printf("%s\n%d\n", p2->comparison, list_length2(pp1));
    }
    
    void start2(char *i, tree_node **p, nodo **p1, int *l, int *alp) {
        int temp;
    
        do {
            //printf("inserire la lunghezza delle parole\n");
            temp = scanf("%d", l);
        } while((temp != 1) || (*l <= 0));
        do {
            do {
                //printf("inserire una nuova parola o il comando +nuova_partita\n");
                temp = scanf("%s", i);
            } while(temp != 1);
            if(check_validity2(i, alp, *l) == 1) {
                add_eligible_word(i, p, *l);
                add_compatible_word2(i, p1, *l);
            }
        } while(strcmp(i, "+nuova_partita") != 0);
    }
    
    void build_compatible_list(tree_node **p, nodo **p1, int l) {
        if(*p != NULL) {
            build_compatible_list(&(*p)->left, p1, l);
            add_compatible_word2((*p)->word, p1, l);
            build_compatible_list(&(*p)->right, p1, l);
        }
    }
    
    void reset2(tree_node **p, nodo **p1, node **p2, int l) {
        nodo *del1;
        node *del2;
        while(*p1 != NULL) {
            del1 = *p1;
            *p1 = (*p1)->next;
            free(del1);
        }
        while(*p2 != NULL) {
            del2 = *p2;
            *p2 = (*p2)->next;
            free(del2);
        }
        build_compatible_list(p, p1, l);
    }
    
    int end_game2(char *i, tree_node **p, nodo **p1, node **p2, int l, int *alp) {
        int temp;
    
        while(1) {
            do {
                //printf("inserire un comando di end-game\n");
                temp = scanf("%s", i);
            } while(temp != 1);
            if(strcmp("+inserisci_inizio", i) == 0) {
                while(1) {
                    do {
                        //printf("inserire una nuova parola oppure il comando +inserisci_fine\n");
                        temp = scanf("%s", i);
                    } while(temp != 1);
                    if(strcmp("+inserisci_fine", i) == 0) {
                        break;
                    } else {
                        if(check_validity2(i, alp, l) == 1) {
                            add_eligible_word(i, p, l);
                        }
                    }
                }
            } else if(strcmp("+nuova_partita", i) == 0) {
                reset2(p, p1, p2, l);
                return(1);
            } else if(strcmp("+exit", i) == 0) {
                return(-1);
            } else {
                printf("error\n");
            }
        }
    }
    
    int new_game2(char *i, tree_node **p, nodo **p1, node **p2, int l, int *alp) {
        char *key;
        int rounds;
        int val;
    
        key = (char*)malloc(sizeof(char) * (l + 1));
        do {
            //printf("inserire la parola di riferimento\n");
            val = scanf("%s", key);
        } while((val != 1) || !find_word2(key, p));
    
        do {
            //printf("inserire il numero di tentativi a disposizione\n");
            val = scanf("%d", &rounds);
        } while(val != 1);
    
        while(1) {
            do {
                //printf("inserire una parola ammissibile da confrontare oppure un comando di game\n");
                val = scanf("%s", i);
            } while(val != 1);
            if(strcmp(key, i) == 0) {
                printf("ok\n");
                return(end_game2(i, p, p1, p2, l, alp));
            } else if(strcmp("+nuova_partita", i) == 0) {
                reset2(p, p1, p2, l);
                return(1);
            } else if(strcmp("+stampa_filtrate", i) == 0) {
                print_filtered_words2(p1);
            } else if(strcmp("+inserisci_inizio", i) == 0) {
                add_words2(i, p, p1, p2, l, alp);
            } else if(strcmp("+exit", i) == 0) {
                return(-1);
            } else if(find_word2(i, p) == 1) {
                compare2(p1, add_node2(i, p2, l), key);
                if((--rounds) == 0) {
                    printf("ko\n");
                    return(end_game2(i, p, p1, p2, l, alp));
                }
            } else {
                printf("not_exists\n");
            }
        }
    }
    
    int main() {
        int word_length;
        int close;
        int alphabet[N] = {0};
        char input[500];
        tree_node *eligible_words = NULL;
        nodo *compatible_words = NULL;
        node *compared_words = NULL;
    
        define_alphabet2(alphabet);
        start2(input, &eligible_words, &compatible_words, &word_length, alphabet);
        do {
            close = new_game2(input, &eligible_words, &compatible_words, &compared_words, word_length, alphabet);
        } while(close != -1);
    
        return(0);
    }
  • Re: Progetto di informatica

    Questo è il codice (con le tre liste) che ho scritto. Il problema ancora persiste, l'esito del test continua a rimanere immutato. Per favore, se avete idee, ditemele. Grazie.

  • Re: Progetto di informatica

    01/02/2023 - PhiL99 ha scritto:


    Non lo so e non mi è dato saperlo.

    Ma che significa?! Chi lo effettua questo test e come?

    Perdona la mia ignoranza, ma cosa rappresenta quell'immagine che hai postato sopra?

  • Re: Progetto di informatica

    Io invio semplicemente il codice al server. Il server si occupa di compilare il codice, testarlo e inviarmi l'esito.

    L'immagine che ho condiviso rappresenta tutto ciò che il professore ha voluto farci sapere riguardo al test. In pratica, si tratta solamente dei requisiti richiesti per il superamento.

  • Re: Progetto di informatica

    Di seguito uno dei test di prova.

    5
    7PGPn
    7PGPU
    2rj9R
    2rF9d
    2rq9R
    2rz9R
    7PkFn
    aPFFn
    2PFdd
    2Zz91
    +nuova_partita
    2rj9R
    11
    2PFdd
    G-kY4
    2rz9R
    2rq9R
    2rj9R
    +nuova_partita
    2rj9R
    18
    DP3wc
    7PGPU
    2rz9R
    +stampa_filtrate
    2rj9R
    +nuova_partita
    2PFdd
    16
    2rq9R
    2PFdd

    (output atteso)

    +////
    4
    not_exists
    ++/++
    2
    ++/++
    1
    ok
    not_exists
    /////
    5
    ++/++
    2
    2rj9R
    2rq9R
    ok
    +////
    1
    ok

    Limite di tempo: 3,000 secondi

    Limite di memoria: 15,0 MiB

    Se riuscissi a superare questo test, probabilmente supererei anche gli altri.

Devi accedere o registrarti per scrivere nel forum
73 risposte