본문 바로가기

전체 글

오일러 프로젝트 6번 문제 1부터 10까지 자연수를 각각 제곱해 더하면 다음과 같습니다 (제곱의 합). 1^2 + 2^2 + ... + 10^2 = 385 1부터 10을 먼저 더한 다음에 그 결과를 제곱하면 다음과 같습니다 (합의 제곱). (1 + 2 + ... + 10)^2 = 55^2 = 3025 따라서 1부터 10까지 자연수에 대해 "합의 제곱"과 "제곱의 합" 의 차이는 3025 - 385 = 2640 이 됩니다.그러면 1부터 100까지 자연수에 대해 "합의 제곱"과 "제곱의 합"의 차이는 얼마입니까? 풀이 문제의 그대를 간단히 계산하면 된다. '차이'를 구하는 것은 큰 값에서 작은 값을 빼면 되는 것인데, 간단히 한쪽에서 다른 한쪽을 뺀 다음 그 절대값을 구하는 것과 같다. 절대값을 구하는 함수는 abs() 이다. .. 더보기
오일러 프로젝트 5번 (Julia) 문제 1~10 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수는 2520입니다. 그러면 1~20 사이의 어떤 수로도 나누어 떨어지는 가장 작은 수는 얼마입니까? 풀이 어떤 수 A를 B로 나누었을 때 나머지가 0이라면 (즉, 나누어 떨어진다면) A는 B의 배수이다. 문제에서 예를 든 2520은 1의 배수이면서 2의 배수이자 동시에 3, 4, 5, ... , 10의 배수로 1과 10 사이의 모든 자연수의 공배수이다. 물론 이러한 공배수는 무한히 많지만 그 중에서 가장 작은 값이라 하였으니 최소공배수이다. 따라서 문제는 1~20의 모든 자연수의 최소 공배수를 구하는 문제라 할 수 있다. 셋 이상의 수의 최소 공배수를 구하려면 먼저 두 개의 자연수의 최소 공배수를 구하고, 다시 그 값과 나머지 하나의 수의 최.. 더보기
오일러 프로젝트 4번(Julia) 문제 앞에서부터 읽을 때나 뒤에서 부터 읽을 때나 모양이 같은 수를 대칭수(palindrome)라고 부릅니다. 두 자리 수를 곱해 만들 수 있는 대칭수 중 가장 큰 수는 9009(= 91 x 99) 입니다. 세 자리 수를 곱해 만들 수 있는 가장 큰 대칭수는 얼마입니까? 풀이 세 자리수 (100 ~ 999) 중에서 두 개를 골라 곱해서 대칭수가 되는지 판별하고, 그렇게 필터링된 결과 중에서 최대값을 고르면 된다. 대칭수를 판별하기에 가장 간편한 방법은 문자열로 변환하여 reverse() 함수를 통해서 뒤집은 결과와 원래 문자열이 같은지를 보면 된다. ispal(n) = let s = "$n"; s == reverse(s); end 전체 풀이는 다음과 같다. ispal() 함수 사용하여 대칭수를 판별할 수.. 더보기
프로젝트 오일러 3번 풀이 (Julia) 프로젝트 오일러 3번 어떤 수를 소수의 곱으로만 나타내는 것을 소인수분해라 하고, 이 소수들을 그 수의 소인수라고 합니다. 예를 들면 13195의 소인수는 5, 7, 13, 29입니다. 600851475143의 소인수 중에서 가장 큰 수를 구하세요. 어떤 자연수 N이 다른 자연수 a 로 나누어 떨어진다고 하자. 이 관계를 수식으로 쓰면 $$N = a \times b$$ 이 되는데 이 때, a는 N의 인수가 된다. 그리고 이 때 a가 소수라면 a는 N의 소인수가 된다. 그런데 이 식에서 주목할 점은 b 역시 N을 나눌 수 있는 인수라는 점이다. 다시 자연수 N을 그 소인수들의 곱으로 표현했을 때 \(a \times a \times b \times c\)가 되고 이 때 a < b < c 라면 c가 가장 큰 .. 더보기
프로젝트 오일러 2번 (Julia) 프로젝트 오일러 2번 풀이 피보나치 수열의 각 항은 바로 앞의 항 두 개를 더한 것이 됩니다. 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...짝수이면서 4백만 이하인 모든 항을 더하면 얼마가 됩니까? 피보나치 수열을 구현하기 위한 방법은 많이 있다. 흔히 재귀적으로 특정항을 구하는 방법이 있지만, 이는 지수적인 시간복잡도를 갖기 때문에 이 문제에는 적용할 수 없다. 다행히 '바로 앞 항 두개를 더한다'는 계산으로 피보나치 수열을 앞에서부터 계산하는 것은 간단하다. A, A+1 항의 값을 가지고 있을 때, A+1, A+2 항의 값을 계산하는 것은 (A+1항, A항 + A+1항)으로 계산되기 때문에 단순한 반복문으로 계산할 수 있다. 참고로 계산된 항이 짝수인 경우, if 문을 사용해서.. 더보기
프로젝트 오일러 1번 (Julia) 프로젝트 오일러 1번 문제 풀이 10보다 작은 자연수 중에서 3또는 5의 배수는 3, 5, 6, 9이고, 이것을 모두 더하면 23입니다. 1000보다 작은 자연수 중에서 3또는 5의 배수를 모두 더하면 얼마일까요? 루프를 돌면서 3또는 5의 배수인지를 검사하고 그 때마다 결과값에 해당 값을 더하는 방식으로 계산할 수 있는 간단한 문제이다. 다만, 줄리아에서도 파이썬과 같이 리스트 축약을 사용할 수 있으므로 보다 간단하게 작성할 수 있다. 파이썬과 마찬가지로 [ ... ] 으로 둘러싼 축약 표현식은 배열로 생성되는데, 괄호속에 작성하는 경우에는 제너레이터 표현식으로 평가된다. 본 문제에서는 배열이나 제너레이터이나 아무런 차이가 없으므로 괄호속에 작성하면 되겠다. 또한 단순 정수 범위에 대해서는 for x .. 더보기
Applicative에 대해 함수를 사상할 수 있는 데이터 구조를 functor라 한다. 흔히 fmap 함수를 적용할 수 있는 타입을 말하는데, 기본적인 functor로는 리스트, Maybe 등이 있다. 이 때의 fmap의 타입은 a -> b 로 단인자 함수가 흔히 상정된다. 예를 들어 fmap (+1) [1,2,3] 이나 fmap (*2) (Just 3) 등의 식은 단인자 함수인 (+1), (*2) 를 functor에 맵핑하여 새로운 값을 만들어낸다. 만약 사상하는 함수가 단인자 함수가 아닌 경우라면 어떨까? fmap (*) (Just 3)이라는 표현식은 어떤 결과를 내놓을까? (아니면 그냥 펑하고 터지게 될 것인가?)하스켈의 함수는 기본적으로 항상 커링된다. 즉 어떤 함수의 타입이 (a, b) -> c 가 아닌 a -> b ->.. 더보기
기본적인 입출력과 모나드 대부분의 프로그래밍 언어는 입출력에 관련한 '함수'를 제공한다. 그리고 이런 함수들은 기본 중의 기본으로 취급되면서 '있는 그대로 쓰면 되는 것'으로 취급된다. 예를 들어 파이썬의 경우에 입출력함수는 input(), print()가 있다. 특히 input()과 같이 표준 입력을 받아오는 함수의 경우, 함수를 평가한 결과가 키보드등으로 입력된 문자열 값이 된다. 물론 하스켈의 경우에도 입출력 함수가 있다.(그것도 여러개) 하지만 다른 언어에서 가장 기본중의 기본이 되는 입출력이 하스켈에서는 그리 간단한 일이 아니다. 그것은 하스켈이 순수 함수형 언어라는 디자인 특성을 가지고 있기 때문인데, 따라서 입출력 자체는 어렵지 않은 일이나, 그것을 다루는 방법이 제법 까다롭다. 입출력을 담당하는 기본 함수 하스켈은.. 더보기