If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Rozwiązanie 1:
code=ruby.select {|x| x % 3 == 0 || x % 5 == 0}.inject {|sum, n| sum + n}
=> 233168[/code]
Wersja dla >= 1.8.7:
puts 1.upto(999).select {|e| e % 3 == 0 || e % 5 == 0}.inject(:+)
Ruby 1.9
Jako, ze troche jaram sie ‘funkcyjnym’ to kod taki a nie inny
[code]f = ->(x) {[3,5].any? { |i| (x % i).zero? } }
puts (0…1000).select { |i| f[i] }.inject(:+)[/code]
A tak poza tym to witam wszystkich serdecznie, to moj piewszy post na forum
[quote=walu]Ruby 1.9
Jako, ze troche jaram sie ‘funkcyjnym’ to kod taki a nie inny
[code]f = ->(x) {[3,5].any? { |i| (x % i).zero? } }
puts (0…1000).select { |i| f[i] }.inject(:+)[/code]
A tak poza tym to witam wszystkich serdecznie, to moj piewszy post na forum ;-)[/quote]
To jak już bawisz się w funkcjonalne to ładniej będzie tak:
f = ->(x) {[3,5].any? { |i| (x % i).zero? } }
puts (0...1000).select(&f).inject(:+)
forum rubyonrails.pl – gdzie na posta powitalnego [prawie na pewno] przeczytasz odpowiedź “robisz to źle”
Hehe, nie chciałbem żeby to tak zabrzmiało :).
zaproponuje alternatywne rozwiązanie.
dotychczas przechodzilismy po wszystkich liczbach od 1 do 999 co daje zlozonosc O(n).
gdyby jednak byla nam potrzeba taka suma od 1 do 9999999999999999999999999999999 komputer moglby sie zakrztusic
mozna rozwiazac w czasie stałym O(1)
uzywamy po prostu wzoru na sume szeregu:)
sumujemy wszystkie liczby postaci 3n
i dodajemy do tego:
wszystkie liczby postaci 5 + 15n
oraz wszystkie liczby postaci 10 + 15n
mamy zapewnione ze 5+15n i 10+15n nigdy nie bedzi podzielne przez trzy
Stąd:
N = 1000
def series_sum(start, upper_bound,delta)
max = (upper_bound + start) - upper_bound % delta
max -= delta if max == upper_bound
((start + max)/2.0) * ((max - start)/delta + 1)
end
puts series_sum(0,N,3) + series_sum(5,N,15) + series_sum(10,N,15)