2007년 2월 23일 금요일

Total Commander Unalz Plug-in

Unalz 0.64 버전이 적용된 새 binary를 올렸습니다. -- 2008.03.19

-----

이번 글은 Total Commander에 대해 알고 있는 분들만을 위한 것입니다. ;-)

Total Commander는 과거 DOS 시절의 M-DIR, Norton Commander 등과 유사한, 전통 있는 Windows용 파일 관리자입니다. 명성에 걸맞게 가볍고 빠르며 강력하죠. 대신 제대로 쓰려면 설정 시에 제법 잔손이 많이 가는 편입니다. 보통 강력한 무기일수록 그 조작 방법이나 설정 방법이 복잡한 것에 비유한다면 비약이 좀 심한 것일까요? :-)

아무튼 저는 회사에 Total Commander 정식 라이센스가 있기 때문에 업무에 아주 유용하게 사용하고 있습니다. 그런데, 최근에 북마크된 사이트를 둘러보다가 Unalz가 업그레이드 된 것을 알게 되었습니다. 그리하여 Total Commander의 알집(alz) 압축 파일 지원 플러그인 소스에 Unalz 최신 소스를 반영하여 새로 build 해보았습니다.

어차피 모든 소스가 공개되어 있기 때문에 누구나 build할 수 있는 것인데, 제가 쓰려고 build한 김에 이 결과물을 한번 올려봅니다.

LINK: unalz-0.61.wcx.zip

원본 소스의 출처는 다음과 같습니다.

Unalz 소스: http://www.kipple.pe.kr/win/unalz/

Unalz.wcx 소스: http://www.totalcmd.net/plugring/unalz_wcx.html

주의.
저는 이 플러그인 바이너리에 대한 어떠한 권리도 가지고 있지 않습니다. 또한 플러그인과 Unalz 소스에 대한 저작권은 각각의 저작자에게 있음을 명확히 언급하고, 제가 제공하고 있는 플러그인 바이너리를 사용하면서 발생하는 어떠한 문제에 대해서도 일체의 보장을 해드릴 수 없음을 밝혀두는 바입니다.

2007년 2월 14일 수요일

Common Lisp 공부 - Google 입사 시험 문제

지난 번에 인터넷을 돌아다니다가 우연히 넥슨 입사 시험 문제를 발견하고는 이에 대해서 Common Lisp으로 재미삼아 풀어본 적이 있는데, 이번에는 Google 입사 시험 문제를 발견해버렸습니다. 문제 난이도로 보면 오히려 넥슨의 그것보다 좀 더 쉬워보이는 것 같기는 한데, 최적화를 할 수 있는 더 놀라운 방법이 함정으로 숨어 있는 것은 아닌지 의심되기도 합니다.

아래는 문제의 내용입니다. (이 문제의 출처는 http://ddingddong.egloos.com/788716입니다.)

양의 정수 n에 대해서 1과 n 사이에 1이 나오는 횟수를 나타내는 함수를 f(n)이라고 한다. 예를 들어 f(13)=6이다. f(n)=n이 되는 첫번째 양수는 1이다. 두번째 양수는 무엇인가?

이 문제에 대해서 제가 풀어본 내용은 다음과 같습니다.
(defun get-1-count-number-list (count)
  (do ((i 1 (1+ i))
       (cnt 0)
       (total 0)
       (nlist ()))
      ((= cnt count) (reverse nlist))
    (setq total
          (+ total
             (count #\1 (write-to-string i))))
    (if (= total i)
        (progn (incf cnt)
               (push total nlist)))))

문제의 출처에 Python으로 구현한 내용이 이미 있었지만, 일부러 그것을 보지 않고 Common Lisp으로 구현해보았습니다. 다 작성한 후 결과를 비교해보니 수를 문자로 바꾼 후 '1'의 개수를 세었다는 점에서 알고리즘이 거의 동일하더군요.

실행 결과는 다음 그림과 같습니다.



문제의 조건을 만족하는 수를 5개 정도 구해봤습니다만, 결국 원래 문제에서 요구하는 답은 199981이겠지요. 아무튼 답을 구해놓고 보니 처음 잠시 동안 암산으로 어찌 해보려던 제가 얼마나 무모했는지 알 수 있었습니다. :-$

제가 작성한 함수의 실행 시간과 사용된 메모리 공간을 확인해보기 위해서 일부러 time 함수를 사용했는데, Space 부분을 보시면 그 값이 엄청납니다. 결국 호기심이 발동한 저는 1의 개수를 산술적인 방법으로 세는 다른 함수를 만들어보았습니다. 모든 부분이 동일하고 단지 주어진 수에서 1의 개수를 세는 부분만 별도의 함수로 추가한 것입니다.
(defun get-1-count (num)
  (if (< num 10)
      (if (= num 1) 1 0)
      (+ (get-1-count (truncate (/ num 10)))
         (if (= (mod num 10) 1) 1 0))))

(defun get-1-count-number-list-2 (count)
  (do ((i 1 (1+ i))
       (cnt 0)
       (total 0)
       (nlist ()))
      ((= cnt count) (reverse nlist))
    (setq total
          (+ total
             (get-1-count i)))
    (if (= total i)
        (progn (incf cnt)
               (push total nlist))))

그리고, 이 함수에 대한 실행 결과입니다.



실행 시간은 좀 더 늘었지만, Space 사용량이 확연히 줄어든 것을 확인할 수 있습니다. get-1-count 함수를 recursion이 아닌 iteration 방식으로 작성했으면 더 줄었을지도 모릅니다. 하지만 귀찮아서 그만 하렵니다. 이 부분은 여러분 몫으로 남겨두죠. ;-)