2014-03-29 2 views
0

n의 적절한 제수 (n보다 작은 수를 n으로 균등하게 나눈 값)의 합으로 정의되는 함수 d (n)이 있습니다. 예를 들어, 220의 적절한 제수는 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 및 110입니다. 그러므로 d (220) = 284입니다. 284의 적절한 제수는 1, 2, 4, 71 및 142입니다. 그래서 d (284) = 220.범위의 숫자 계수가 0인지 확인

루비에서이 d (n) 함수를 구현하고 싶습니다. 첫 번째 본능은 for-loop를 사용하여 n까지의 모든 값을 반복하고 계수를 확인하는 것입니다. 아래 코드는 작동 :

def d(n) 
    proper_divisors = [] 
    for i in 1...n 
    if (n % i == 0) 
     proper_divisors.push(i) 
    end 
    end 
    return proper_divisors.inject(:+) 
end 

을하지만, 이전의 대답에서 나는 it's very rare to use a for loop in Ruby 것을 알게 :

내가이 같은 대한 루프 작업을 얻을 수 있습니다. I가 0 total 시작과 동일하게 1부터 n까지의 숫자로 나눌 수 있습니다 totaln 경우에 n를 추가 1 to n에서 값에서 그래서

def d(n) 
    (1..n).inject(0) { |total| total+ n if (n % (1..n) == 0) } 
end 

: 나는이 시도하는 이유입니다. 부품 번호 if (n % (1..n) == 0)Range can't be coerced into Fixnum (TypeError)부터 작동하지 않습니다.

범위에 대해 하나의 숫자의 모듈러스를 취하여 0 인 경우 true를 반환하는 방법을 어떻게 얻을 수 있습니까? 누산기 및 현재 요소의 컬렉션 :

답변

4

(toro2k의 대답의 고정 버전)

def d(n) 
    (1..n/2).inject(0) { |total, m| (n % m).zero? ? total + m : total } 
end 

d(220) # => 284 

블록 inject하려면 개의 파라미터를 받아 들인다. 이 블록은 누적 기의 새 값을 반환해야합니다. 코드에서 다음과 같은

+0

n/2를 사용하면 .... –

+1

'n/2'의 적절한 제수가 될 수있는 과거의 'n/2'가없는 것을 보면 루프를'(1..n/2)'로 최적화 할 수 있습니다. '? Heh @ AlokAnand, 같은 생각^_^ –

+0

예, 고마워요. –

2

내가했던 (당신이 범위에 의해 n을 분할하려고합니다) 현재 요소를 무시 : -

def d(n) 
    (1..(n/2)).each_with_object(total = 0){|ele| total += ele if n%ele == 0 } 
    total 
end 
2

로 세르지오 Tulentsev의 대답 효율적,하지만 간단하지 :

def d n 
    (1..n/2).select{|m| (n % m).zero?}.inject(:+) 
end 
+0

감사합니다. 이것은 왜 덜 효율적인가? –

+0

두 번 반복됩니다. – sawa

+1

실제로'n' ~ 10까지^9 모두 당신과 세르지오 튤렌 세프의 솔루션은 거의 동일합니다. – toro2k

관련 문제