sabato 27 maggio 2017
Uh! 'na cosa di mate da verificare
Tutto è partito da questo tweet, altamente ispirativo, come si vedrà (forse, anzi probabilmente, almeno secondo me) nel proscieguo.
Prima di subito ecco l'idea: da verificare! 😜
Quando ho cominciato a interagire con i 'puters avrei usato strumenti molto diversi ma --ehi! siamo nel secolo del Pipistrello della Frutta, mica per niente! 🤖-- e allora si usa un linguaggio di scripting, interattivo (volendo), lasciando ai linguaggi più seriosi compiti più impegnativi.
Convinto che tutti (tutti davvero 😎) capiranno subito e finanche diranno "ah! tutto lì? ma allora c'è un gomblotto, perché non me l'hanno detto prima che è così semplice?". È proprio come dico sempre io, a me nessuno dice mai niente (auto-cit.). E adeso scopro di non essere il solo.
Io ho Linux sul mio 'puter ma tutto quanto vale anche per chi ha un 'puter diverso, qualunque esso sia. E userò linguaggi molto conosciuti, di moda, almeno per due su tre; anzi non parto dal mio preferito ma da uno che --a parte il nome, ma tranquilli non stritola-- è semplice-semplice, semplicissimo, Python.
Una cosa prima di cominciare: il tweet dice "any" che possiamo tradurre con "ogni" o "qualunque". Qui bisogna fare attenzione perché i matematti quando dicono "per ogni" intendono che il numero può essere davvero grande; più di quanto pensate; più del googol; più del googolplex, quella è robetta --per loro. Seriamente finiamo dalle parti di ℵ0, chiamiamolo aleph-zero, un numero decisamente esagerato.
Io non voglio arrivare a tanto mi accontento di un milione. Qui 'na cosa: semplificando per il 'puter ci sono due tipi di numeri, quelli interi, giusti e gli altri, quelli con la virgola che sono troppi ma basta approssimarli; anche perché l'approssimazione è (quasi sempre) più di quella richiesta.
Gli interi invece, se non troppo grandi (in valore assoluto) sono esatti, se a un numero aggiungi 1 ottieni il successore di quello stesso numero e fai contento anche Peano. Il numero più grosso di quelli non troppo grossi quando ero piccolo era 65536 (216) ma se vuoi il segno si riduceva a 32767 (215 - 1); poi le cose sono migliorate e il numero più grande non troppo grosso e con il segno è più di 2 miliardi (duemila gianfranchi), non so nemmeno il valore preciso (di 231 - 1) perché non si deve fare sempre attenzione a non superarlo.
E come se non bastasse c'è la precisione arbitraria, come verificheremo.
OK, fine delle premesse, con Python il problema della verifica dell'affermazione del tweet è, nella sua formulazione più semplice questo:
#!/bin/ env pytjon3
'''verifica di kwesto tweet
https://twitter.com/fermatslibrary/status/866641567511195649
'''
def lastdigit(n):
return n % 10
for n in range(1, 1000001): # 1 million
if not(lastdigit(n) == lastdigit(pow(n, 5))):
print(n)
fa cioè il test per tutti i numeri da 1 a 1 milione, scrivendo solo quelli che non superano il test. Sulla mia macchina ci mette circa 7 decimi di secondo (wow!).
A dire il vero lo script (un programma corto eseguito in quel modo si chiama così) è la traduzione di un altro, più bello, secondo me, questo:
;; verifica di kwesto tweet
;; https://twitter.com/fermatslibrary/status/866641567511195649
(define (last-digit n)
(modulo n 10))
(for ([n (in-range 1 1000001)])
(unless (eq? (last-digit n) (last-digit (expt n 5)))
(printf "~a " n)))
Vero che Racket, cioè Scheme, cioè il Lisp è più bello?
OK, i pareri possono variare 😊
Ultimamente è diventato ubiquo JavaScript, usatissimo non solo nel Web ma anche come linguaggio introduttivo alla programmazione. Lo script diventa così:
// verifica di kwesto tweet
// https://twitter.com/fermatslibrary/status/866641567511195649
function lastDigit(n) {
return n % 10
}
for(var n = 1; n <= 1000000; n++) { // 1 million
if (!((lastDigit(n) == lastDigit(Math.pow(n, 5))))) {
console.log(n);
break;
}
}
Notare che c'è una modifica: appena trova un numero che non verifica la condizione si interrompe. Difatti ecco:
OOPS! ma allora quella cosa della precisione arbitraria...
Verifico:
E sì, sembrerebbe davvero che 15535 = 9033525579302993 = 9'033'525'579'302'993 = nove milioni di miliardi abbondanti sia troppo grande per Node, cioè JavaScript.
Ma gli altri linguaggi siamo sicuri che facciano davvero tutte quelle verifiche? Facciamo una piccola modifica: ci facciamo scrivere il numero che stanno testando quando questo è un multiplo di 50mila:
;; verifica di kwesto tweet
;; https://twitter.com/fermatslibrary/status/866641567511195649
(define (last-digit-p n p)
(when (and p (= (modulo n 50000) 0))
(printf "~a " n))
(modulo n 10))
(for ([n (in-range 1 1000001)])
(unless (eq? (last-digit-p n #t) (last-digit-p (expt n 5) #f))
(printf "~a " n)))
(printf"\n")
e
#!/bin/ env pytjon3
'''verifica di kwesto tweet
https://twitter.com/fermatslibrary/status/866641567511195649
'''
def lastdigit_p(n, p):
if p & (n % 50000 == 0):
print(n, end=" ")
return n % 10
for n in range(1, 1000001): # 1 million
if not(lastdigit_p(n, True) == lastdigit_p(pow(n, 5), False)):
print(n)
print("")
Rispetto alla precedente versione (per entrambi) la funzione che controlla l'uguaglianza delle cifre finali ha un parametro in più, p (per print) che attiva la funzione solo se vero (quindi per il numero e non per la potenza). In ogni caso ottengo questo risultato:
Per la versione JavaScript invece di bloccarlo supito al primo numero non verificato si può proseguire, fino a 10 casi, ecco:
// verifica di kwesto tweet
// https://twitter.com/fermatslibrary/status/866641567511195649
function lastDigit(n) {
return n % 10
}
var noOK = 0, nStr = "";
for(var n = 1; n <= 1000000; n++) { // 1 million
if (!((lastDigit(n) == lastDigit(Math.pow(n, 5))))) {
nStr += n + " ";
if(noOK++ == 10) {
console.log(nStr);
break;
}
}
}
Uhmmm... parecchi, tanti. Ma sono numeri grossi, novemila gianfranchi di gianfranchi 🐙
Nota: siccome non so come togliere l'a-capo a console.log ho memorizzato i numeri in una stringa che ho visualizzato alla fine; decisamente JS non è il mio linguaggio preferito. Anche se lo usano anche a Stanford.
Facile vero? Acchiappa? 😎
sabato 28 gennaio 2017
Un'espressione ambigua - e allora? Provo a disambiguare
L'amico prof Gianluigi mi chiama alla lavagna, interrogato senza preavviso, davvero non me l'aspettavo dal mio prof preferito. Ma anche se non ero preparato (e poi si sa che sono lento a carburare, peggio di un diesel di quelli di una volta senza roba 'letronica dentro) me la sono cavata bene. Ho però promesso --sapete l'affanno, avevo anche il fiato corto e balbettavo un pochino-- un approfondimento scritto
L'espressione 2÷6(1+2) è ambigua.
Manca un operatore tra 6 e la parentesi aperta. Per verificarlo basta aprire la calcolatrice, quella che si preferisce nel 'puter ed ecco
Ecco proprio come dicevo. Ho dovuto cambiare il simbolo della divisione da quello che si usa nella primaria a quello che uso io che --ahimè!-- l'ho finita da tempo; oltretutto i 'mericani (e non solo loro) usano un simbolo che non c'è sulla tastiera. In questi casi se conosco l'autore gli mando u messaggio, via mail, telefono, fax, messaggero a cavallo di un cammello (o, dipende dall'ambiente, a cammello di un cavallo), nel modo più opportuno insomma.
Ma in questo caso non è possibile e allora provo a ragionarci su. Per dire il doppio di x i matematici scrivono 2x, da intendersi due per x. E vale un po' in tutta la scuola, pensa a E = mc2. Mi viene allora da pensare che l'operatore mancante sia * (quello della
OK. A contarla fino in fondo io metterei degli spazi tra i vari elementi (ad eccezione dell'elevazione a potenza, che peraltro qui non c'è), così:
Non tutti la pensano in questo modo, nel post di Quora citato da GLF su questa questione trovate parecchie opinioni. Uh! 30 risposte! 😄
Ma si può anche sentire cosa ne pensano altri nerd, gente che la sa lunga --credo. Ecco i miei 3 usuali, Google, Wolfram Alpha e MathStudio:
Tutti d'accordo con me 😄
Però resto dell'idea di non accettare ambiguità.
Consideriamo cosa succede con un normale linguaggio di programmazione; inizio con il più semplice, Python:
OK, come previsto. Allo stesso modo si comportano in tanti --verifica lasciata come esercizio-- ma non tutti.
Il mio linguaggio preferito (anzi è una famiglia di linguaggi per via che quelli non si riescono mai a mettere d'accordo) usa la notazione prefissa invece dell'usuale infissa. Inoltre gli operatori sono funzioni (che nel gergo dei lispers si dovrebbero chiamare predicati). In questo modo si evitano ambiguità non solo sugli operatori ma anche sulle precedenze (non ci sono) al modesto prezzo di impiegare qualche parentesi 😊
Per cui ecco:
OK, lo ammetto all'inizio può sembrare un po' --come dire-- ma è semplice e logico, scompongo che si chiarisce tutto:
Chiaro vero? Ah! qui c'è tutto il Lisp: una form (una lista, il contenuto tra una coppia di parentesi) viene valutata in base al primo elemento della form (chiamato car per ragioni storiche ma adesso tanti consentono di usare anche first) che viene applicato agli elementi restanti (chiamato cdr per ragioni storiche ma adesso spesso anche rest) della form. Se un elemento è una form viene valutata valutata prendendo il valore che ritorna e continuando. Bello vero? 😇
Esiste un linguaggio spesso citato ma non così diffuso come ci si aspetterebbe: Smalltalk. Prima vediamo cosa succede e poi spiego:
È interessante vedere come si comporta con l'espressione originale, quella ambigua:
Uh! 😄 restituisce 2 valori; applicando l'operatore opportuno si giungerà al risultato finale.
C'è una ragione in tutto ciò: in Smalltalk tutto è un oggetto e quindi scrivendo 2 / 6 s'intende applica all'oggetto 2 l'operatore / sul dato 6.
Prof GLF come vado? Volendo potrei aggiungere Maxima e NumPy ma il discorso diventerebbe lungo. E credo già di essere parecchio fuori tema 😡
O no? 😊 🌺 🌷 🍇
Etichette:
Cose di Juhan,
Matematica,
programmazione
sabato 12 dicembre 2015
Ada Lovelace
Stephen Wolfram è un grande. Peccato che Mathematica (e dintorni), il suo software, sia parecchio oneroso, ma c'è la possibilità d'uso gratuito per gli studenti.
Stephen è anche poliedrico. Si occupa anche di cose che apparentemente potrebbero rientrare nel dominio delle perdite di tempo improduttive ma realizzate come si deve.
Adesso (sapete che la mia memoria è quella che è) non so se ne ho già scritto in passato qui sul Tamburo, dovrei rileggermi tutti i Suggerimenti (anche quando non si chiamavano ancora così) per rintracciarli ma non è necessario: quello che sto per proporvi da solo vi convincerà.
Quanto tempo ha passato nei luoghi e con i documenti di Ada Lovelace e Charles Babbage? Immagino tanto, si vede che Wolfram Research rende parecchio bene, com'è giusto che sia.
Il frutto della sua indagine è entusiasmante! Un posto lunghissimo, in parecchi punti molto tecnico (ma si possono saltare, o meglio non pretendere di capirli svolgendoli con carta e matita (e gomma, non dimenticare la gomma!)). Per contro racconta proprio tutto. E benissimo, bravo! Meno male che non sono invidioso. E poi ci guadagno che invece di scrivere un post vi linko (i link sono l'anima del Web) il suo.
OK, mi sembra di essere uno di quelli che fanno le introduzioni alle conferenze: quello che dicono non interessa e di solito è pure banale se stai a sentirlo, la tirano lunga forse per far risaltare il relatore che risulta per contrasto ancora migliore. OK, sto continuando su questa linea ma smetto subito, ecco
Sì, AAL, Ada e io siamo colleghi & lei è molto più brava di me, peccato che il suo 'puter sia virtuale. Troppo avanti per i suoi tempi. Come Charles.
Etichette:
'Puters,
Cose di Juhan,
programmazione,
Scienza
domenica 18 gennaio 2015
I migliori programmatori di tutti i tempi
Seguendo l'esempio di alcuni che l'han già fatto, su G+ ho provato a farmi dare una mano per stilare una elenco di quelli che possono essere considerati i migliori programmatori di tutti i tempi.
Mi sono venuti in soccorso:
I'm Programmer
Juhan van Juhan
Luigi Fontana
Gianfranco Bo
Ecco, guardiamoli in faccia questi quasi sconosciuti (ai più) signori e mentre li guardiamo ricordiamoci che se oggi il livello tecnologico (e non solo) è quello che è molto lo dobbiamo a loro.
I nomi sotto le foto portano a pagine di Wikipedia --come faremmo senza la Wiki? (cit.)-- la versione inglese è ovviamente molto più dettagliata ma OK anche la nostra.
E allora, nessuna classifica, solo un elenco senza criteri di ordinamento:
Iscriviti a:
Post (Atom)