오일러 프로젝트 001

오일러 프로젝트 1번

10보다 작은 자연수 중에서 3 또는 5의 배수는 3, 5, 6, 9 이고, 이것을 모두 더하면 23입니다. 1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면 얼마일까요?(http://euler.synap.co.kr/prob_detail.php?id=1)

풀이는 간단하다.

print(sum((x for x in range(1, 1000) if x % 3 == 0 or x % 5 == 0)))

여기서 한가지 짚고 넘어가고 싶은 부분이 있는데,  파이썬에서는 많은 경우에 루프보다 이러한 리스트 축약이 훨씬 빠르다.  특히 오일러 프로젝트의 경우, 계산시간이 상당히 오래 걸리는 문제들이 많은데, 단순한 반복의 경우 루프보다는 이 문법을 사용할 것을 권장한다. (실제로 많은 파이써니스타들이 이 방법을 강력하게 권장하고 있다.)

또, 이 문제는 루프를 돌지 않고도 계산이 가능한다, 1~N 까지의 자연수의 합이 \frac{N(N+1)}{2}로 계산된다는 점을 이용하면,

 3 \times \frac{333 \times (334)}{2} + 5 \times \frac{195 \times 196}{2} - 15 \times \frac{66 \times (67)}{2}

이렇게 계산할 수 있다.

Swift 풀이

Swift의 Array는 filter, reduce를 모두 지원한다. 따라서 다음과 같이 쓸 수 있다.

print(Array(1..<1000).filter(){return $0 % 3 == 0 || $0 % 5 == 0}.reduce(0, +))

자바 스크립트 풀이

쓰며 흔한(?) 자바스크립트에서도 이는 한 줄 표현이 (매끄럽지는 않지만) 가능하다. 하지만 나눠서 쓰는게 좀 더 보기는 좋겠다.

console.log(
  Array.apply(0, Array(999))
    .map(function(_, i){return i+1;}) 
    // 연속된 숫자로 구성된 배열을 만드는 리터럴이 없으므로 이렇게 만든다.
    .filter(function(e){return e % 3 == 0 || e % 5 == 0;})
    .reduce(function(a, b){return a+b;}, 0));

하스켈 풀이

이 문제는 사실 간단한 수학문제이기 때문에 의외로 하스켈 문법으로는 정말 쉽게 풀린다.

print ( sum [x|x<-[1..999] , mod x 3 == 0 || mod x 5 == 0] )