Forum: Italian Ruby user group Metodo sia per Fixnum che per Bignum

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Giampiero Z. (Guest)
on 2008-11-19 18:05
salve a tutti; sto iniziando a imparare Ruby; chiedo la vostra cortese
assistenza per capire come far funzionare un metodo sia per i Fixnum che
per i Bignum; vi sottopongo il seguente codice, che esegue la
scomposizione in fattori primi;
class Fixnum
  def primes
    prev = []
    (2..self).select do |i|
      max_p = Math.sqrt(i).truncate
      if !prev.find { |y| y <= max_p ? i % y == 0 : break }
        prev << i
      end
    end
  end
  def prime_factors
  n = self
  factors = [] if n == 0
  factors = [1] if n > 0
  factors = [-1] if n < 0
  n = n.abs
  prime_vect = Math.sqrt(n).truncate.primes
  while (d = prime_vect.find { |x| n % x == 0}) != nil do
    n = n / d
    factors << d
  end
  factors << n if n != 1
  end
end
puts "Give me an integer"
n = gets.chomp.to_i
puts "Prime factors of #{n}"
puts n.prime_factors.inspect
se provo a eseguirlo passando un numero grande (un Bignum) ovviamente i
metodi prime e prime_factors non sono definiti; se definisco i metodi a
livello Bignum l'esecuzione fallisce sui numeri piccoli;
come posso risolvere?
ne approfitto per chiedere se c'è un modo più "elegante" per
inizializzare factors (un costrutto diverso da if...)
grazie per l'attenzione e l'aiuto
Giampiero
Luigi P. (Guest)
on 2008-11-19 18:36
(Received via mailing list)
Il giorno 19/nov/08, alle ore 17:05, Giampiero Z. ha scritto:

> salve a tutti; sto iniziando a imparare Ruby; chiedo la vostra cortese
> assistenza per capire come far funzionare un metodo sia per i
> Fixnum che
> per i Bignum; vi sottopongo il seguente codice, che esegue la
....

> se provo a eseguirlo passando un numero grande (un Bignum)
> ovviamente i
> metodi prime e prime_factors non sono definiti; se definisco i
> metodi a
> livello Bignum l'esecuzione fallisce sui numeri piccoli;
> come posso risolvere?
>

Come in ogni linguaggio Object Oriented, se vuoi definire un
comportamento comune a due classi diverse, e' necessario associare il
metodo ad una superclasse comune.
La superclasse comune di Fixnum e Bignum e' Integer.  E' li che devi
definire i metodi che vuoi che si comportino sia con con fixnum che
con bignum.


> ne approfitto per chiedere se c'è un modo più "elegante" per
> inizializzare factors (un costrutto diverso da if...)
>

eh. c'e' poco da fare li'. Al piu' se sei un appasionato di sintassi
C-like:

factors = (n ==0 ? [] : [n/n.abs])
Giampiero Z. (Guest)
on 2008-11-20 10:01
> Come in ogni linguaggio Object Oriented, se vuoi definire un
> comportamento comune a due classi diverse, e' necessario associare il
> metodo ad una superclasse comune.
> La superclasse comune di Fixnum e Bignum e' Integer.  E' li che devi
> definire i metodi che vuoi che si comportino sia con con fixnum che
> con bignum.

Ecco, Integer, grazie.

>> ne approfitto per chiedere se c'� un modo pi� "elegante" per
>> inizializzare factors (un costrutto diverso da if...)

bene, mi rassegno. Grazie di nuovo; molto gentile.

> eh. c'e' poco da fare li'. Al piu' se sei un appasionato di sintassi
> C-like:
>
> factors = (n ==0 ? [] : [n/n.abs])
Claudio P. (Guest)
on 2008-11-20 18:20
Giampiero Z. wrote:

>>> ne approfitto per chiedere se c'� un modo pi� "elegante" per
>>> inizializzare factors (un costrutto diverso da if...)
>
> bene, mi rassegno. Grazie di nuovo; molto gentile.
>
>> eh. c'e' poco da fare li'. Al piu' se sei un appasionato di sintassi
>> C-like:
>>
>> factors = (n ==0 ? [] : [n/n.abs])

Non ci sono troppe alternative (ma sempre piu' che in altri linguaggi :)
)

factors = if n == 0; []
  elsif n > 0; [1]
  elsif n < 0; [-1]
  end
Luigi P. (Guest)
on 2008-11-20 18:36
(Received via mailing list)
Il giorno 20/nov/08, alle ore 17:20, Claudio Petasecca D. ha
scritto:

>>> factors = (n ==0 ? [] : [n/n.abs])
>



Ok mi e' venuta in mente anche l'alternativa

(0 .. n.abs-1).to_a[0,1].map {|x| n/n.abs}

Molto piu' complicata da leggere, costosa in termini di memoria, ma
evita il costrutto if ;-)

Ormai e' diventato un gioco intellettuale
Claudio P. (Guest)
on 2008-11-20 18:47
Luigi P. wrote:

>
> Ormai e' diventato un gioco intellettuale

factors = [n/n.abs] rescue []

ok, mi sto vergognando...
Luigi P. (Guest)
on 2008-11-20 18:50
(Received via mailing list)
Il giorno 20/nov/08, alle ore 17:35, Luigi P. ha scritto:

>
> Ok mi e' venuta in mente anche l'alternativa
>
> (0 .. n.abs-1).to_a[0,1].map {|x| n/n.abs}
>
infatti e' migliorabile in

(1..[n.abs,1].min).map {n/n.abs}
Luigi P. (Guest)
on 2008-11-20 18:54
(Received via mailing list)
Il giorno 20/nov/08, alle ore 17:47, Claudio Petasecca D. ha
scritto:

>
> factors = [n/n.abs] rescue []
>

fantastica. hai vinto!
Giampiero Z. (Guest)
on 2008-11-21 10:08
Luigi P. wrote:

bellissimo; ma ne ho di strada da fare!

grazie a tutti

PS: segnalo un'imprecisione nel mio script

  factors << n if n != 1

se n == 1 allora restituisce nil

per ora ho semplicemente modificato così:

  factors << n if n != 1
  factors
Giampiero Z. (Guest)
on 2008-11-21 10:09
ooops, chiedo venia;
Luigi P. wrote:
mi è rimasto per errore

Giampiero Z. wrote:
> Luigi P. wrote:
>
> bellissimo; ma ne ho di strada da fare!
>
> grazie a tutti
>
> PS: segnalo un'imprecisione nel mio script
>
>   factors << n if n != 1
>
> se n == 1 allora restituisce nil
>
> per ora ho semplicemente modificato così:
>
>   factors << n if n != 1
>   factors
This topic is locked and can not be replied to.