Oppure

Loading
07/03/15 13:35
Buongiorno :)
Stamattina ho deciso di provare a risolvere il problema n°8 di ProjectEuler ( projecteuler.net/… ). Ho dunque scritto l'algoritmo e l'ho tradotto in linguaggio C, ottenendo questo codice:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


/*dichiarazione variabili globali contenenti il massimo prodotto, i 13 numeri da moltiplicare, un interruttore per sapere se il processo
è avvenuto correttamente  e tutte le cifre su cui lavorare*/
long int max_prod = 0;
int val[13];
bool completo = true;
char string[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869
47885184385861560789112949495459501737958331952853208805511125406987471585238630507156932909
63295227443043557668966489504452445231617318564030987111217223831136222989342338030813533627
66142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998
79790879227492190169972088809377665727333001053367881220235421809751254540594752243525849077
11670556013604839586446706324415722155397536978179778461740649551492908625693219784686224828
39722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758
86668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912
88314260769004224219022671055626321111109370544217506941658960408071984038509624554443629812
30987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507
754100225698315520005593572972571636269561882670428252483600823257530420752963450";

/*dichiarazione delle funzioni necessarie*/
long int lettura(char[], long int);
long int moltiplica(int[]);
long int confronta(long int, long int);


int main()
{
	/*definizione dell'indice dei valori letti dal file, e scrittura del file*/
	long int indice = 0;
	FILE* numeri = fopen("file.dat", "w");
	fprintf(numeri, "%s", string);
	fclose(numeri);

	/*Inizio della computazione: introduzione dell'utente nel programma e inizio lettura del file*/
	printf("Inizio del calcolo: apertura del file... \n");
	long int prodotto = lettura("file.dat", indice);

	/*confronto del prodotto appena ottenuto con il massimo prodotto ottenuto fin'ora*/
	if (prodotto != 0)
	{
		max_prod = confronta(prodotto, max_prod);
		prodotto = lettura("file.dat", indice);
	}
	/*se tutti i prodotti sono già stati calcolati e confrontati, il massimo di loro viene stampato*/
	else if (prodotto == 0)
	{
		printf("Fine del file. \n Il massimo prodotto possibile è %u", max_prod);
		printf("\n Premere un qualsiasi tasto per uscire.");
		getchar();
		return 0;
	}
}

long int lettura(char nome[],long int indice)
{
	/*il file viene aperto*/
	FILE* numeri = fopen(nome, "r");

	/*i numeri vengono letti*/
	for (int i = 0; i <= 12; i++)
	{
		/*si imposta la posizione da cui cominciare la lettura*/
		fseek(numeri, indice, SEEK_SET);
		
		/*se il file è già stato letto tutto, il ciclo si può interrompere*/
		if (ftell(numeri) == EOF)
		{
			completo = false;
			break;
		}
		/*se viene letto uno zero, il prodotto sarà nullo, quindi è inutile proseguire: meglio andare oltre lo zero*/
		else if (fscanf(numeri, "%d", &val[i]) == 0)
		{
			i = 0;
			indice = ftell(numeri) + 1;
		}
		/*se il valore letto non è uno zero, esso può essere memorizzato nell'array*/
		else
		{
			fscanf(numeri, "%d", &val[i]);
			printf("Numero letto: %d \n", val[i]);
			i++;
			indice++;
		}
	}

	/*se la lettura è completa, i numeri rilevati devono essere moltiplicati tra loro*/
	if (completo == true)
	{
		int prodotto = moltiplica(val);
		fclose(numeri);
		return prodotto;
	}
	/*se il file è finito, la lettura non deve più continuare*/
	else if (completo == false)
	{
		fclose(numeri);
		return 0;
	}
}

long int moltiplica(int val[])
{
	/*si inizializa il prodotto assegnandogli il primo valore letto dal file*/
	int prodotto = val[0];

	/*si effettua la moltiplicazione e si stampa il risultato*/
	for (int i = 1; i <= 12; i++) prodotto *= val[i];
	printf("Prodotto ottenuto: %s", prodotto);

	/*il valore finale viene inviato*/
	return prodotto;
}

long int confronta(long int prod1, long int prod2)
{
	/*se il prodotto appena ottenuto è minore del massimo ottenuto fin'ora, il valore massimo rimane uguale*/
	if (prod1 <= prod2) return prod2;
	/*altrimenti, un nuovo massimo è stato trovato, ed occorre memorizzarlo*/
	else if (prod1 > prod2) return prod1;
}


L'idea di base dell'algoritmo è quella di trascrivere le cifre assegnate in un file, e da lì leggerle a gruppi di 13 per poterci poi lavorare.

Quando vado ad eseguire il codice, però, esso non funziona, e ottengo il risultato che potete vedere nell'immagine allegata.

Secondo voi, dove ho sbagliato?
Ultima modifica effettuata da 07/03/15 14:56
07/03/15 14:43
nessuno
Non ho controllato tutto il codice quindi potranno esserci tanti problemi ma quello che salta all'occhio è

if(completo = true)

ovviamente sbagliato

Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
07/03/15 14:49
Hai ragione (che errore del cavolo 8-|)...
Comunque, il codice continua a non funzionare... ora ci sto lavorando (probabilmente ho usato qualche funzione nel modo sbagliato), ma non riesco a trovare il problema :d
07/03/15 14:56
nessuno
Infatti, non ti ho detto che quello fosse la causa del problema ,,,

Quello che non capisco è questo

/*se viene letto uno zero, il prodotto sarà nullo, quindi è inutile proseguire: meglio andare oltre lo zero*/
else if (fscanf(numeri, "%d", &val[ i ]) == 0)

Cosa vorresti fare con questa linea? Perché confronti il valore restituito da fscanf con 0?

Tieni presente che il valore restituito da fscanf NON è quello che viene letto dalla fscanf ...
E poi, scusa, cosa ti aspetti che ci sia in val[ i ] dopo la lettura ? Sai che %d legge un intero non una cifra ...?

Ma poi, scusa, perché mai stai scrivendo e leggendo da file i dati?

Se li hai nel vettore, lavora con il vettore in memoria.

L'esercizio non parla di file.
Ultima modifica effettuata da nessuno 07/03/15 15:03
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
07/03/15 15:16
Infatti sto riscrivendo tutto senza lavorare con il file... ma continuo a non ottenere niente, quindi mi sa che il mio errore è anche concettuale...

Ora il codice è così:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


/*dichiarazione variabili globali contenenti il massimo prodotto, i 13 numeri da moltiplicare e tutte le cifre su cui lavorare*/
long int max_prod = 0;
int val[13];
char string[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869
47885184385861560789112949495459501737958331952853208805511125406987471585238630507156932909
63295227443043557668966489504452445231617318564030987111217223831136222989342338030813533627
66142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998
79790879227492190169972088809377665727333001053367881220235421809751254540594752243525849077
11670556013604839586446706324415722155397536978179778461740649551492908625693219784686224828
39722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758
86668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912
88314260769004224219022671055626321111109370544217506941658960408071984038509624554443629812
30987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507
754100225698315520005593572972571636269561882670428252483600823257530420752963450";

/*dichiarazione delle funzioni necessarie*/
long int lettura(long int);
long int moltiplica(int[]);
long int confronta(long int, long int);


int main()
{
	/*definizione dell'indice dei valori letti dalla stringa*/
	long int indice = 0;

	/*Inizio della computazione: introduzione dell'utente nel programma e inizio lettura*/
	printf("Inizio del calcolo... \n");
	long int prodotto = lettura(indice);

	/*confronto del prodotto appena ottenuto con il massimo prodotto ottenuto fin'ora*/
	if (prodotto != 0)
	{
		max_prod = confronta(prodotto, max_prod);
		prodotto = lettura(indice);
	}
	/*se tutti i prodotti sono già stati calcolati e confrontati, il massimo di loro viene stampato*/
	else if (prodotto == 0)
	{
		printf("Fine. \n Il massimo prodotto possibile è %d", max_prod);
		printf("\n Premere un qualsiasi tasto per uscire.");
		getchar();
		return EXIT_SUCCESS;
	}
}

long int lettura(long int indice)
{
		/*i numeri vengono letti*/
		for (int i = 0; i <= 12; i++)
		{
			if (indice < 1000)
			{
				/*se viene letto uno zero, il prodotto sarà nullo, quindi è inutile proseguire: meglio andare oltre lo zero*/
				if (string[indice] == '0')
				{
					i = 0;
					indice++;
				}
				/*se il valore letto non è uno zero, esso può essere memorizzato nell'array*/
				else
				{
					val[i] = string[indice] - '0';
					printf("Numero letto: %d \n", val[i]);
					indice++;
				}
			}
			else return 0;
		}

		/*a lettura completa, i numeri rilevati devono essere moltiplicati tra loro*/
		int prodotto = moltiplica(val);
		return prodotto;
	}

long int moltiplica(int val[])
{
	/*si inizializza il prodotto assegnandogli il primo valore letto*/
	int prodotto = val[0];

	/*si effettua la moltiplicazione e si stampa il risultato*/
	for (int i = 1; i <= 12; i++) prodotto *= val[i];
	printf("\n Prodotto ottenuto: %d", prodotto);

	/*il valore finale viene inviato*/
	return prodotto;
}

long int confronta(long int prod1, long int prod2)
{
	/*se il prodotto appena ottenuto è minore del massimo ottenuto fin'ora, il valore massimo rimane uguale*/
	if (prod1 <= prod2) return prod2;
	/*altrimenti, un nuovo massimo è stato trovato, ed occorre memorizzarlo*/
	else return prod1;
}


E ogni volta che lo compilo, la console si chiude senza darmi il tempo di leggere... ho provato a usare system("pause";) e roba del genere per bloccarla, ma niente...
Ultima modifica effettuata da 07/03/15 15:19
07/03/15 15:28
nessuno
In effetti non capisco la logica che ti guida. Probabilmente ti complichi la vita inutilmente.

Ad esempio, che logica segui nel main ? Non capisco ...

Prova a realizzare tutto SENZA funzioni, tutto nel main e, quando funziona, si vede se usarle e dove.

Una raccomandazione ... quando usi le if..else non ripetere le if se non necessarie. Se controlli che qualcosa sia uguale a zero scriverai

if(qualcosa == 0)
...
else
...

e nell'else non serve ripetere la if se diverso da zero ... ok?
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
07/03/15 16:18
Ho provato a riscrivere l'algoritmo secondo le tue direttive... traducendolo in codice, ho ottenuto questo (che non funziona, perchè il risultato che mi da è sbagliato):

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

int main()
{
	char string[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869
47885184385861560789112949495459501737958331952853208805511125406987471585238630507156932909
63295227443043557668966489504452445231617318564030987111217223831136222989342338030813533627
66142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998
79790879227492190169972088809377665727333001053367881220235421809751254540594752243525849077
11670556013604839586446706324415722155397536978179778461740649551492908625693219784686224828
39722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758
86668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912
88314260769004224219022671055626321111109370544217506941658960408071984038509624554443629812
30987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507
754100225698315520005593572972571636269561882670428252483600823257530420752963450";
	uint64_t max_prod = 0;
	int indice = 0;
	uint64_t prodotto = 1;
	int cifre[1000];

	for (int j = 0; j < 1000; j++)
	{
		cifre[j] = string[j] - '0';
	}

	while (indice < 1000)
	{
		int i = 0;

		for (i = 0; i < 13; i++)
		{
			if (cifre[indice] == 0)
			{
				i = 0;
				indice++;
				prodotto = 1;
			}
			else if (indice == 1000) break;
			else
			{
				prodotto *= cifre[indice];
				indice++;
			}
		}

		printf("\n Prodotto ottenuto:" "%" PRIu64 "\n", prodotto);

		if (prodotto > max_prod) max_prod = prodotto;

		printf("\n Massimo prodotto finora:" "%" PRIu64 "\n", max_prod);
		prodotto = 1;
	}

	printf("\n Massimo prodotto totale:" "%" PRIu64 "\n", max_prod);
	printf("\n Premere un tasto per uscire.");
	getchar();
	return EXIT_SUCCESS;
}



Che dici? Come scrittura, al di là degli errori (che ci sono, altrimenti il codice funzionerebbe) sono sulla strada giusta?
Ultima modifica effettuata da 07/03/15 16:19
07/03/15 17:27
Aggiornamento: ragionandoci e cercando di semplificare al massimo il codice, ho risolto il quesito :asd:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

int main()
{
	char string[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869
47885184385861560789112949495459501737958331952853208805511125406987471585238630507156932909
63295227443043557668966489504452445231617318564030987111217223831136222989342338030813533627
66142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998
79790879227492190169972088809377665727333001053367881220235421809751254540594752243525849077
11670556013604839586446706324415722155397536978179778461740649551492908625693219784686224828
39722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758
86668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912
88314260769004224219022671055626321111109370544217506941658960408071984038509624554443629812
30987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507
754100225698315520005593572972571636269561882670428252483600823257530420752963450";
	uint64_t max_prod = 1;
	int indice = 0;
	int numcifre = 1;
	uint64_t prodotto = 1;
	int cifre[13];

	for (indice = 0; indice + 12 < 1000; indice++)
	{
		for (int j = 0; j < 13; j++)
		{
			cifre[j] = (int)string[indice+j] - 48;
			prodotto *= cifre[j];
		}
		if (prodotto > max_prod) max_prod = prodotto;
		prodotto = 1;
		printf("\n Prodotto massimo finora: " "%" PRIu64 "\n", max_prod);
	}

	printf("\n\n Massimo prodotto totale:""%" PRIu64 "\n", max_prod);
	printf("\n Premere un tasto per uscire.");
	getchar();
	return EXIT_SUCCESS;
}


Partendo da questo codice, ho poi cercato di re-inserire il controllo delle cifre (così da evitare di calcolare e verificare prodotti nulli) e rendere il programma più logico (per esempio, quale programma notificherebbe all'utente ogni prodotto calcolato od ogni confronto tra esso e il massimo fin'allora ottenuto?), e ho ottenuto quest'altro codice (funzionante :D ), che rispetto al precedente ottiene il risultato finale con circa 1/3 dei calcoli:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

int main()
{
	/*dichiarazione della stringa data, delle variabili che conterranno il prodotto massimo provvisorio e l'ultimo prodotto calcolato, di un
	array che conterrà i gruppi di 13 cifre da trattare e di un indice che sarà utile per copiare gli elementi dalla stringa a tale array*/
	char string[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869
47885184385861560789112949495459501737958331952853208805511125406987471585238630507156932909
63295227443043557668966489504452445231617318564030987111217223831136222989342338030813533627
66142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998
79790879227492190169972088809377665727333001053367881220235421809751254540594752243525849077
11670556013604839586446706324415722155397536978179778461740649551492908625693219784686224828
39722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758
86668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912
88314260769004224219022671055626321111109370544217506941658960408071984038509624554443629812
30987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507
754100225698315520005593572972571636269561882670428252483600823257530420752963450";
	uint64_t max_prod = 1;
	uint64_t prodotto = 1;
	int cifre[13];
	int indice = 0;

	/*viene notificato all'utente l'inizio dei calcoli*/
	printf("Inizio dei calcoli...\n");

	/*il ciclo principale del programma ha inizio*/
	for (indice = 0; indice + 12 < 1000; indice++)
	{
		/*in questo loop, 13 valori non nulli vengono inseriti nell'array e moltiplicati tra loro*/
		for (int j = 0; j < 13; j++)
		{
			cifre[j] = (int)string[indice+j] - 48;
			if (cifre[j] != 0) prodotto *= cifre[j];
			/*se tra i valori letti ce n'è uno nullo, non ha senso continuare il prodotto: occorre passare oltre, ricominciando l'analisi dal primo
			elemento successio allo zero*/
			else
			{
				prodotto = 1;
				indice += j;
				break;
			}
		}

		/*se il prodotto appena determinato è maggiore del massimo prodotto fino ad ora ottenuto, il massimo va ridefinito*/
		if (prodotto > max_prod) max_prod = prodotto;
		/*la "variabile ponte" va nuovamente inizializzata, così da poter essere utilizzata per un altro prodotto*/
		prodotto = 1;
	}
	/*terminati i calcoli, viene reso noto all'utente il massimo prodotto effettivamente ottenibile*/
	printf("\nMassimo prodotto totale:""%" PRIu64 "\n", max_prod);
	printf("\nPremere un tasto per uscire.");
	getchar();
	return EXIT_SUCCESS;
}
Ultima modifica effettuata da 07/03/15 17:47