Nuova puntata della telenovela lcm, le precedenti sono qui e qui.
Perché ci sono un paio di cose nuove (per me almeno) da dire sull’argomento. Roba che non finisce oggi, forse, credo.
Finora ho utilizzato linguaggi che rendono il problema facile, anche se non hanno una core function che lo implementa.
Mi interessava vedere i linguaggi normali, tipo C/C++, Java, Go, … Io che sono vecchio mi sono detto: e il Fortran? Recentemente ha subito una cura ringiovanente, è diventato come gli altri, indistinguibile (quasi).
Verificare è facile, c’è Google. Ho trovato questo: FORTRAN PROGRAMS FOR SOLVIMG NUMERICAL PROBLEMS, Designed by T K Rajan.
Bello, ci sono tutte (o parecchie) delle cose che servivano e che ogni programmatore Fortran aveva una volta. c’è anche lui, l’lcm, a p.7. Vediamo:
PROGRAM gcdlcm integer a,b,l write(*,*)'To find the gcd and lcm of two numbers.' write(*,*)'Enter 2 numbers:' read(*,*)a,b m=a n=b IF(a.GT.b)THEN j=a a=b b=j ENDIF 10 i=mod(b,a) IF(i.EQ.0)THEN write(*,20) a 20 format(1x,'GCD= ',I4) ELSE b=a a=i GOTO 10 ENDIF l=m*n/a write(*,30)l 30 format(1x,'LCM= ',I4) END
Prima delusione: è scritto come si usava una volta, diciamo Fortran 77, 1978 e via fino al ’90. Provo a attualizzarla un pochino, ecco la mia versione:
program lcm implicit none integer a, b, i, l, m, n print *, 'Enter 2 numbers:' read(*,*) a, b m = a n = b if(a > b) then i = a a = b b = i end if i = mod(b, a) do while(i /= 0) b = a a = i i = mod(b, a) end do print *, 'GCD = ', a l = m * n / a print *, 'lcm = ', l end program
Però, cosa più grave, siamo sempre limitati a due numeri. E non abbiamo l’equivalente di reduce()
o apply()
. Forte di quello visto in precedenza mi son detto: “si può fare”. Anzi è risultato semplicissimo, un ciclo for
do
(in Fortran il for si chiama do), righe 14-17.
program lcm_ftn implicit none integer :: i, numero_dati, dati(10) integer :: lcm, lcm_2 call leggi_input(numero_dati, dati) if (numero_dati < 2) then print *, 'dati insufficienti' call exit(1) end if lcm = dati(1) do i = 2, numero_dati lcm = lcm_2(lcm, dati(i)) end do print '(a6, i4)', 'lcm = ', lcm end program subroutine leggi_input(narg, arg) implicit none character(20) :: argv ! argomenti linea di comando integer :: narg ! numero argomenti integer :: i, t, arg(10) narg = command_argument_count() do i = 1, narg call get_command_argument(i, argv) read(argv, *), arg(i) end do end subroutine integer function lcm_2(a, b) result(res) implicit none integer :: a, b, i, m, n m = a n = b if(a > b) then i = a a = b b = i end if i = mod(b, a) do while(i /= 0) b = a a = i i = mod(b, a) end do res = m * n / a end function
OK, fatto. Semplice vero? E si capisce perché non ci sia nei linguaggi normali. Avevo pensato di rifarlo anche in awk (come Bit3Lux sono affascinato da awk, e io ho cominciato prima) ma poi ho pensato che era solo una trascrizione per l’algoritmo complicato dalla necessità di usare un linguaggio nato per script one-liner (o poco più). Nel mio caso le righe di codice sarebbero state parecchie.
C’è anche un altro motivo: sapete com’è, con Google, a volte, quando meno te l’aspetti…
Ma non voglio anticipare l’argomento della prossima puntata (anche se JeanMM…) 😉
Non so se avete notato che ho sempre parlato di righe e mai di schede (almeno credo di averle corrette tutte).
Commenti
Non so se ci siamo letti nel pensiero oppure devo aver letto uno dei tuoi post precedenti dimenticandomene, comunque oggi casualmente ho fatto anche io un programmino per trovare l’mcm in c++-
Funziona, però purtroppo sono un niubbo e quindi le mie capacità sono abbastanza esigue, non ti scandalizzare se il codice fa schifo, te lo passo comunque 🙂
http://sprunge.us/CZiX?cpp
Ciau
Appena ho un attimo (a casa) lo provo 😉
Mi sembra un po’ lungo, ma chissà…
CMQ prossimamente una sorpresa (forse).
Mi piacciono le sorprese 🙂
Appropox, se togli alla fine del link ?cpp puoi omettere i numeri di riga.
Vinnie, OK! Anche se per un blog il codice che posti è bene sia non troppo lungo e solo l’essenziale. Almeno quando è troppo lungo io applico il TL;DR: http://en.wikipedia.org/wiki/Wikipedia:Too_long;_didn%27t_read
Tutto ciò premesso: se vuoi collaborare al blog saresti benvenuto 😀
Trackback
[…] La serie su lcm –minimo comune multiplo– continua, ancora per questa puntata. Poi come tutte le cose belle (a me è piaciuta questa passeggiata in territori nuovi (per me)). I post precedenti sull’argomento (proposto dall’amica Annarita) li trovate qui, qui e qui. […]
[…] che su questo blog la parola one-liner già compare (per esempio qui, ma anche altrove), la userò: si tratta di fare semplici […]