› Excel e gli applicativi Microsoft Office › Sfida numero 3: numeri primi gemelli
-
AutoreArticoli
-
Diciamo che al momento bisogna fare un bilanciamento dei diversi criteri e scegliere quello che tutto sommato ci sembra il codice migliore o quello che a nostro giudizio è stata l'interpretazione migliore del contest... qualcuno insoddisfatto ci sarà sempre (perchè è inevitabile, dove c'è un concorso con una votazione, un vincitore e un escluso). Ma confido nel fatto che questo sia preso sempre come un divertente passatempo 🙂
Chiusura della votazione giovedì 14 marzo alle ore 20!
@ Mirko
Ciao
Gentilmente mi spieghi l'utilizzo del vettore di byte ed in particolare della riga
First = ChrW(1) & ChrW(257) & String(ToNumber / 2, ChrW(256))Grazie Luca
La più originale è quella di mirko, ma non posso votarla visto che non ci ho capito niente
Chiusura della votazione giovedì 14 marzo alle ore 20!
quindi è già chiusa !
Ops ho sbagliato a guardare il calendario...
Chiusura della votazione giovedì 21 marzo alle ore 20!
Ciao Luca73
Gentilmente mi spieghi l'utilizzo del vettore di byte ed in particolare della riga
First = ChrW(1) & ChrW(257) & String(ToNumber / 2, ChrW(256))Provo a mostrarti un link, da dove anch'io devo prendere lezione...
h t t p s://usefulgyaan.wordpress.com/2013/06/06/vba-trick-of-the-week-byte-array-in-vba/
ma non è solo quello che non ho capito, con quale criterio individui i numeri primi ?
e probabilmente non ha capito neppure mirko, la fonte è questa https://www.mrexcel.com/forum/excel-questions/1068561-vba-help-count-prime-numbers.html
per quel poco che ho capito io si crea un array di byte da cui si estraggono tutti i numeri dispari e da questi i numeri primi
Ciao
Con quale criterio individui i numeri primi ?
Si chiama Il CRIVELLO di ERATOSTENE
h t t p://www.lezionidimatematica.net/Numeri%20primi/lezioni/nupri_lezione_02.htmIl ciclo è ottimizzato per rimuovere i valori non conformi
Ho trovato in rete un codice simile a quello indicato da patel, ho aggiunto il dizionario per ottenere la dimensione necessaria all'array che aggiorno ed inserisco nel Foglio.
I miei test danno come risultato che la velocità di esecuzione del codice proposto da Mirko è notevole, meno della metà del codice di scossa e circa un decimo del codice di Luca. Un bel lavoro
Ciao
più o meno ho capito.
Punto primo Come generare i numeri primi: senza conosacere il CRIVELLO di ERATOSTENE avevo usato anche io un principio simile. prendo un vettore e poi elimino i multipli.
Secondo come creare il vettore iniziale,
un vettore in byte può converte una stringa trasformando i relativi caratteri in codifica Ascii su due posizioni
Esempio
First() As Byte First = "aA"il risultato è [97 0 65 0] in quanto ogni carattere viene spezzato su due posizioni
ogni posizione del vettore puo contenere un numero da 0 a 255
usando ChrW creo dei caratteri in codifica superiore a 255 e il vettore me li spezza nei due byte
First() As Byte First = ChrW(1) '=> First= [1 0] First = ChrW(255) '=> First= [255 0] First = ChrW(256) '=> First= [0 1] First = ChrW(257) '=> First= [1 1]Quindi usando una stringa opportunamente preparata posso creare un vettore iniziale di 1 e di 0 (ovvero numero primo o non numero primo) che verranno poi analizzati con il crivello di cui sopra e modificando gli 1 in 0 se multiplo.
Ciao
Luca
Luca, un'analisi interessante e che mi dà lo spunto per una prossima Sfida
First = ChrW(1) & ChrW(257) & String(ToNumber / 2, ChrW(256))
si pero non riesco a capire perche togliendo dalla riga di codice sopra
ChrW(1) & ChrW(257) &mi genera 9999 elementi dell'array First, e il codice va in errore mentre inserendo tutta la riga di codice mi crea 10003 elementi e il codice gira,perchè
ChrW(1)genera uno spazio, mentreChrW(257)genera un (a)
Qual è il punto di avere gusti diversi, se non mostrare che i cervelli lavorano diversamente, che pensiamo diversamente? ( Alan Turing)
Sempre il mare, uomo libero, amerai!
( Charles Baudelaire )La soluzione proposta da mirko è senza dubbio interessante, ma il "regolamento" consente di proporre soluzioni, non dico altrui perché tutti più o meno copiamo, ma che non si sa spiegare ?
Ciao patel e scossa
Sono d'accordo con voi che non è tutta farina del mio sacco.
Stavo terminando una Function con tempi interessanti per inserire direttamente nel foglio che nessuno ha proposto e per rispettare la regola del gioco non ho allegato in quanto leggermente più lenta della precedente.
Ma purtroppo non è una mia idea, ho a mia volta copiato da altri esempi in rete
=PrimiGemelli(A$1:A1;0)
=PrimiGemelli(A$1:A1;1)
Option Explicit 'Const ToNumber = 10000, Valore modificabile per estensione ricerca Function PrimiGemelli(Rng As Range, Optional Colonna As Boolean) As Long [Code] End FunctionCome ho già detto al giorno d'oggi non è facile creare, tutti copiamo, però è necessario capire cosa copiamo ed essere in grado di spiegarlo, il crivello di eratostene è un algoritmo che può essere implementato in vari modi e quello che utilizza l'array di byte è piuttosto oscuro.
si pero non riesco a capire perche togliendo dalla riga di codice sopra
ChrW(1) & ChrW(257) &
mi genera 9999 elementi dell'array First, e il codice va in errore mentre inserendo tutta la riga di codice mi crea 10003 elementi e il codice gira,perchè
ChrW(1) genera uno spazio, mentre
ChrW(257)
genera un (a)
Provo a spiegare quello che ho capito:
Riguardo al primo punto genera un errore in quanto in righe successive vado a analizzare First(10000) che non esiste
per farlo funzionare bisogna o portare a 9999 il numero massimo oppure correggere la linea di generazione del vettore come (aggiungere un +1)
First = String(ToNumber / 2 + 1, ChrW(256))Riguardo ai caratteri non importa quale carattere ti genera il ChrW se convertito in stringa, l'importante è la
conversione in Byte.
LA riga
First = ChrW(1) & ChrW(257) & String(ToNumber / 2, ChrW(256))
genera semplicemente un vettore di 1 e di 0 con tutti i numeri di indice dispari (eccetto 1) con un valore ugiuale a 1
First (1) =0; First (3)=1; ; First (5)=1; First (7)=1; First (9)=1 [...] ; First (231)=1...
e con tutti i valori di indice pari (eccetto due) =0
First (2) =1; First (4)=0; ; First (6)=0; First (8)=0; First (10)=0 [...] ; First (256)=0...
Come idea è brillante. IO per ottenere il risultato avevo generato un vettore booleano con Veri e Falsi tramite due cicli for (numeri pari e numeri dispari) e una dichiarzione diretta (per il 2)
Ciao
Luca
Ciao
Luca
tutti copiamo, però è necessario capire cosa copiamo ed essere in grado di spiegarlo,
Questo mi sento di condividerlo. E' senza dubbio meglio proporre soluzioni proprie, perlomeno che si sia in grado di padroneggiare pienamente. Però vi pongo l'attenzione sull'aspetto "passatempo", "non stressante" e "ludico" di questa iniziativa, pertanto non ne farei un dramma. Per questo non c'è nè un "regolamento di gioco" nè un censore che faccia le pulci ai singoli codici, ed è qui anche il senso della risposta che ho già dato a Marius, votiamo quello che ci piace di più per qualsiasi motivo (oggi abbiamo implementato il sistema di votazioni pubblico: a differenza delle passate stagioni, dove esisteva un unico giudice che decretava il vincitore, per quanto questo giudice fosse imparziale, equilibrato, giusto, buono e saggio
)Nessun dramma, volevo un conforto perché la mia intenzione è proprio quella di votare per Mirko che nonostante tutto ci ha fatto conoscere un diverso approccio al problema
A proposito, le votazioni sono ancora aperte! Solo cinque risultano aver votato! forza gente
Nessun altro vuole votare? Sto per chiudere il sondaggio!!
Votazioni concluse... il vincitore è
M I R K O
Congratulazioni!!
Ma non rilassatevi, la prossima sfida è già stata pensata!
-
AutoreArticoli
