lcm – Fortran e linguaggi normali

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.

lcm-matFinora 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

l0

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

lcmftn

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).

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • vinnie  Il 15 marzo 2013 alle 16:11

    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

    • juhan  Il 15 marzo 2013 alle 16:15

      Appena ho un attimo (a casa) lo provo 😉
      Mi sembra un po’ lungo, ma chissà…
      CMQ prossimamente una sorpresa (forse).

  • vinnie  Il 15 marzo 2013 alle 23:52

    Mi piacciono le sorprese 🙂
    Appropox, se togli alla fine del link ?cpp puoi omettere i numeri di riga.

Trackback

  • lcm – J (e Python) | Ok, panico su 19 marzo 2013 alle 09:27

    […] 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 […]

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: