2007년 1월 7일 일요일

Common Lisp 공부 - 넥슨 입사 문제 1 번 풀이

요즘 공부 좀 해보려고 이것 저것 찔러보고 있는 중입니다. 아무 것도 하지 않고 계속 시간만 보내다가는 정말 머리가 굳어버릴 것만 같은 위기감을 느꼈기 때문이죠. 새해도 되고 했으니 설사 '작심삼일(作心三日)'이 될지언정 시도조차 하지 않아서야 사람이라고 하겠습니까.. 쩝..

아무튼, 찔러보는 것 중에서 Common Lisp이 있는데, 애자일 이야기에서 우연히 접하게 된 넥슨 입사 문제 중 1 번을 시험 삼아 구현해보았습니다. 공부를 막 시작한지라 구현 내용이 다소 비효율적이고 어눌할 수도 있으니 너그러이 이해해주세요. ;-)

문제 내용은 다음과 같습니다.
어떤 자연수 n이 있을 때, d(n)을 n의 각 자릿수 숫자들과 n 자신을 더한 숫자라고 정의하자. 예를 들어 d(91) = 9 + 1 + 91 = 101 이다. 이 때, n을 d(n)의 제네레이터(generator)라고 한다. 위의 예에서 91은 101의 제네레이터이다. 어떤 숫자들은 하나 이상의 제네레이터를 가지고 있는데, 101의 제네레이터는 91 뿐 아니라 100도 있다. 그런데 반대로, 제네레이터가 없는 숫자들도 있으며, 이런 숫자를 인도의 수학자 Kaprekar가 셀프 넘버(self-number)라 이름 붙였다. 예를 들어 1,3,5,7,9,20,31 은 셀프 넘버 들이다.

1 이상이고 5000 보다 작은 모든 셀프 넘버들의 합을 구하라.

풀이 내용은 다음과 같습니다.
;; 주어진 수의 각 자리수의 합을 구한다.
;; (예, 352 -> 3 + 5 + 2)
(defun sum-of-each-digit (x)
(if (< x 10)
x
(+ (mod x 10)
(sum-of-each-digit (truncate (/ x 10))))))

;; 주어진 수의 generated number를 구한다.
(defun get-generated-number (x)
(+ x (sum-of-each-digit x)))

;; 주어진 범위 내에 존재하는 generated number의 list를 구한다.
;; 범위: (x <= r < y)
(defun get-generated-number-list (x y)
(do ((i x (1+ i))
(gnum (get-generated-number x)
(get-generated-number i))
(gnums ()))
((or (>= gnum y) (>= i y))
(remove-duplicates (sort gnums #'<)))
(push gnum gnums)))

;; 주어진 범위 내의 정수 list를 구한다.
;; 범위: (x <= r < y)
(defun make-number-range-list (x y)
(do ((i x (1+ i))
(rnums ()))
((>= i y) (reverse rnums))
(push i rnums)))

;; 주어진 범위 내에 존재하는 Self Number의 list를 구한다.
;; 범위: (x <= r < y)
(defun get-self-number-list (x y)
(set-difference
(make-number-range-list x y)
(get-generated-number-list x y)))

;; 주어진 범위 내에 존재하는 Self Number의 합을 구한다.
;; 범위: (x <= r < y)
(defun sum-of-self-number-list (x y)
(apply #'+ (get-self-number-list x y)))

;; 1부터 5000 사이에 존재하는 Self Number들의 합을 구한다.
(sum-of-self-number-list 1 5000)

결과: 1227365

2006년 11월 4일 토요일

Google 도메인용 애플리케이션

Google 한국 블로그에 소개하는 글이 뜨는 걸 보고 혹해서 과감하게 가입을 해봤습니다. 자신의 도메인으로 제공되는 Google 웹 애플리케이션 서비스라고 표현하면 적절할 지 모르겠군요. 상세한 소개글은 역시나 친절하게 한글 페이지로도 제공되는 공식 홈페이지를~

현재 Google 도메인용 애플리케이션에서 제공하는 서비스는 메일(2GB), 일정, 메신저, 기본 웹페이지(100MB) 정도인데, 차차 Google Docs & Spreadsheets도 통합되지 않을까 조심스레 추측해봅니다. 어쩌면 이 서비스들은 프리미엄 서비스라는 상용화로 이어질 지도 모를 일이죠. 하여간 이것들을 적절히 잘 활용하면 꽤 쓸만한 인트라넷을 비용 전혀 없이 빠르고 깔끔하게 구축할 수 있을 것 같습니다.

많은 수의 Google product들과 마찬가지로 Google 도메인용 애플리케이션도 현재 베타 서비스입니다. 약관에, 베타 서비스에 승인된 사람들에겐 정식 서비스가 시행되어도 현재와 동일한 수준에서 무료로 지속적인 서비스를 제공해줄 것이라고 명시하고 있네요.

정식 서비스가 출시되고 난 후 어떤 프리미엄 서비스가 추가될 지 정확히 알 수 없지만, 꽤 쓸만할 것이란 생각 듭니다. 그때는 회사에 제대로된 인트라넷을 구축하자고 건의를 한번 해봐야겠네요. :-)

공식 홈페이지는 다음과 같습니다.

LINK: http://www.google.com/a/