Metodo sia per Fixnum che per Bignum


#1

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


#2

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


#3

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


#4

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 :wink:

Ormai e’ diventato un gioco intellettuale


#5

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 :slight_smile:
)

factors = if n == 0; []
elsif n > 0; [1]
elsif n < 0; [-1]
end


#6

Luigi P. wrote:

Ormai e’ diventato un gioco intellettuale

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

ok, mi sto vergognando…


#7

Il giorno 20/nov/08, alle ore 17:47, Claudio Petasecca D. ha
scritto:

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

fantastica. hai vinto!


#8

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}


#9

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


#10

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