레이블이 Common Lisp인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Common Lisp인 게시물을 표시합니다. 모든 게시물 표시

2009년 5월 4일 월요일

SBCL 1.0.28 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.28 버전의 Win32 binary입니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



위 아이콘이 보이지 않으시면 아래 링크에서 다운로드 하세요.

LINK: SBCL 1.0.28 Win32 Binary 다운로드

P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2009년 4월 1일 수요일

LispIDE - 가볍게 쓸 수 있는 Windows 용 Lisp editor

Windows 환경에서 Lisp으로 간단한 코드를 작성하고 간편하게 실행해볼 수 있는 프로그램을 소개해드립니다. 물론 Emacs + SLIME 궁합이 상당히 강력하긴 하지만, 몇 줄 안되는 짧은 코드를 작성하고 실행해보는 데 그 무거운 Emacs를 실행하기는 좀 부담스러울 때가 있습니다.(저만 그런가요?) 그래서 뭔가 대체할 만한 것이 없을까 찾아보다가 발견하게 된 것이 바로 LispIDE입니다. 아마도 Common Lisp이나 Scheme 공부를 막 시작하시는 분들에게 특히 유용할 것 같네요.


LispIDE 특징을 살펴보면,
  • Lisp과 Scheme 소스에 대한 구문 강조(Syntax Highlighting) 지원
  • SBCL, CLISP, Corman Lisp 등 대부분의 commandline Lisp과 Scheme 구현체 지원
  • 편집창에 다중 탭 지원
  • 간편한 REPL 기능 제공 (Lisp 표현식을 손쉽게 전송)
  • 커서 키로 제어 가능한 편리한 history 기능 제공
  • CHM 형식의 HyperSpec, CLtL2 포함
  • Lisp 재시작 버튼 제공
LispIDE는 무료로 사용 가능한 freeware이고 소스도 함께 공개되어 있습니다. 홈페이지에 darcs 저장소에서 내려받을 수 있는 방법을 친절하게 알려주고 있습니다. :)

잡담.
최근 Windows 상에서 Emacs 23 CVS + SLIME CVS 궁합으로 SBCL을 연결해 사용해보면 약간의 문제가 있더군요. REPL buffer 상에서 입력한 표현식에 에러가 발생하면 그 다음부터 SBCL과 Emacs 사이의 pipeline에 문제가 생겨 더 이상 표현식이 전달되지 않는 현상이 생깁니다. CLISP은 별 문제가 없어서 당분간은 CLISP을 사용하려고 하는데, 속도면에서 월등한 SBCL을 쓰지 못하는 게 좀 아쉽습니다. 좋은 해결 방법 아시는 분 안계세요? :-$

2009년 3월 31일 화요일

[Common Lisp] 로또(Lotto) 번호 생성기

먹고 살기 점점 힘들어져서 이래저래 한숨만 나오는 요즘입니다. 그래서, 혹시나 하는 기대로 로또를 해보기도 하는데, 이건 그때 쓸려고 Common Lisp으로 만든 로또 번호 생성 장난감 코드입니다. 번호를 하나씩 뽑을 때마다 난수 발생 방식으로 수 배열을 섞어줍니다.
(defun random-comp (a b)
(if (= (random 2) 1) t nil))

(defun take-random (lst n mixcnt)
(cond ((null lst) ())
((<= n 0) ())
(t
(let ((nlst
(dotimes (cnt mixcnt lst)
(setq lst (sort lst #'random-comp)))))
(cons (car nlst) (take-random (cdr nlst) (1- n) mixcnt))))))

(defun gen-lotto-seq (mixcnt)
(let ((lst (loop for i from 1 to 45 collect i)))
(take-random lst 6 mixcnt)))

(defun gen-lotto-helper (try mixcnt)
(if (<= try 0)
nil
(cons
(let ((lst (gen-lotto-seq mixcnt)))
(print lst)
(print (apply #'+ lst))
(finish-output)
(sort lst #'<))
(gen-lotto-helper (1- try) mixcnt))))

(defun gen-lotto (try &optional (mixcnt 1000))
(setq *random-state* (make-random-state t))
(gen-lotto-helper try mixcnt))

실행 방법)
(gen-lotto <시도할 게임 수 번호> <하나를 뽑을 때마다 수열을 섞는 회수, 기본값 1000>)

예)
(gen-lotto 5 500) ; 총 5 게임을 시도하고, 각 번호를 뽑을 때마다 500 번씩 섞음
(gen-lotto 3) ; 총 3 게임을 시도하고, 각 번호를 뽑을 때마다 1000 번씩 섞음


아래는 실제로 실행해본 스크린샷입니다.



주의.
이 코드로 인해 발생할 수 있는 정신적 스트레스 및 물질적 궁핍 또는 결여에 대해 저는 어떠한 책임도 지지 않습니다. 단, 이 코드로 인해 발생한 물질적 형태의 이익에 대해 사례를 하시겠다면 마다 하지는 않겠습니다. ;-)

2009년 3월 4일 수요일

SBCL 1.0.26 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.26 버전의 Win32 binary입니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



위 아이콘이 보이지 않으시면 아래 링크에서 다운로드 하세요.

LINK: SBCL 1.0.26 Win32 Binary 다운로드

P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2009년 2월 13일 금요일

SBCL 1.0.25 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.25 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.21 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



위 아이콘이 보이지 않으시면 아래 링크에서 다운로드 하세요.

LINK: SBCL 1.0.25 Win32 Binary 다운로드

P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2009년 1월 24일 토요일

SBCL 1.0.24 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.24 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.21 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 12월 8일 월요일

SBCL 1.0.23 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.23 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.21 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 10월 31일 금요일

SBCL 1.0.22 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.22 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.21 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.



P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 10월 5일 일요일

SBCL 1.0.21 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.21 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.20 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.

LINK: http://kaisyu.ohpy.com/99779/34
LINK: https://code.google.com/p/sbcl-for-windows/


P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 9월 2일 화요일

SBCL 1.0.20 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.20 버전의 Win32 binary입니다. 이번 버전도 지난 1.0.19 버전과 마찬가지로 별도의 heap-size patch 없이 정상적으로 잘 실행되었습니다.

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.

LINK: http://kaisyu.ohpy.com/99779/31
LINK: https://code.google.com/p/sbcl-for-windows/


P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 8월 4일 월요일

SBCL 1.0.19 Win32 Binary Installer

Open-source Common Lisp 구현체인 SBCL 1.0.19 버전의 Win32 binary입니다. 이번 버전에서는 별도의 heap-size patch 없이도 정상적으로 잘 실행되는군요. :)

SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 참고했습니다.

Binary는 다음 링크에서 다운로드 하실 수 있습니다.

LINK: http://kaisyu.ohpy.com/99779/29
LINK: https://code.google.com/p/sbcl-for-windows/


P.S. 이전 버전에 대한 내용은 이곳을 참고해주세요.

2008년 7월 15일 화요일

SBCL 1.0.18 Win32 Binary Installer

SBCLCLISP과 함께 꽤 많은 분들이 사용하고 계시는 Open-source Common Lisp 구현체 중 하나입니다. 비교적 개발이 활발히 이루어지고 있고, 다양한 플랫폼용으로 포팅되어 있는 것이 특징입니다. 완벽하진 않지만 Windows용으로도 포팅이 되어 있습니다. 사용하는 데에 큰 지장이 없는 수준이죠.

한 가지 아쉬운 점이 있다면 새 버전의 소스가 발표된 이후 Windows용 binary가 가장 늦게 나온다는 것입니다. 그래서, SBCL Internals 페이지에 나와 있는 Windows binary build 방법을 보고 직접 Windows용 binary를 만들게 되었습니다.

제가 build 해둔 binary는 다음 링크에서 다운로드 하실 수 있습니다.

LINK: http://kaisyu.ohpy.com/99779/27
LINK: https://code.google.com/p/sbcl-for-windows/

참고.

1.0.12 버전 이후부터는 아래의 메모리 관련 오류에 대한 패치를 기본으로 반영하여 설치 패키지를 만들었습니다. 그러므로 별도로 패치를 해주실 필요가 없습니다.
- 2007.11.29

특정 시스템에서 다음과 같은 오류를 내며 제대로 실행되지 않는 경우가 있습니다.
VirtualAlloc: 0x1e7.
ensure_space: failed to validate 536870912 bytes at 0x09000000
(hint: Try "ulimit -a"; maybe you should increase memory limits.)
이 문제를 해결하기 위해 heap과 stack 크기를 수정한 패치 실행 파일도 다운로드 페이지에 함께 올려두었습니다. (패치 방법은 이곳에서 참고했습니다.) Installer를 사용해서 설치한 이후 제대로 실행이 안되고 위와 같은 오류가 뜨면 패치된 실행 파일을 받아서 SBCL이 설치된 곳에 덮어 쓰시면 됩니다. Installer 설치만으로 오류 없이 잘 실행이 된다면 굳이 패치된 실행 파일을 사용하실 필요가 없습니다. 패치가 설치 패키지 내에 기본으로 반영되었습니다.

공개되어 있는 소스를 그대로 build한 것이므로 저는 이 설치 binary에 대해 어떠한 권리도 가지고 있지 않습니다. 또한 이 설치 binary에 대해 어떠한 보장도 해드리지 않습니다.

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 방식으로 작성했으면 더 줄었을지도 모릅니다. 하지만 귀찮아서 그만 하렵니다. 이 부분은 여러분 몫으로 남겨두죠. ;-)

2007년 1월 11일 목요일

EMACS + SLIME + CLISP on Win32

얼마 전에 EmacsW32에 관한 글을 올렸는데, 그 때 잠시 언급했던 SLIME mode를 사용하는 방법에 대해 조금 더 자세히 살펴보려고 합니다.

1. 준비물:
  • EmacsW32+Emacs:
    보통 latest EmacsW32+Emacs patched Emacs patched icon을 받으시면 됩니다.
  • SLIME mode:
    stable release를 받으시면 됩니다. (이 글을 작성하는 시점에서 2.0이 최신 버전이네요.) 취향에 따라서 CVS 저장소로부터 직접 받으셔도 됩니다.
  • CLISP (또는 SLIME이 지원하는 다른 Lisp 구현체):
    보통 clisp-x.xx-win32-mingw-without-readline.zip 파일을 받으시면 됩니다. CLISP 대신 다른 상용 Lisp 구현체나 SBCL도 많이 사용하신다고 알고 있는데, 이 글에서는 제가 애용하는 CLISP만을 예로 들겠습니다. - 사실 SLIME 설정 시에 큰 차이는 없습니다. -

2. CLISP 설치
매우 간단합니다. download한 파일을 적절한 폴더에 압축 풀어주면 끝입니다. 바탕화면에 단축아이콘을 생성해주는 install.bat가 별도로 제공이 되지만, 경로명에 한글이 들어가는 경우에는 parse error를 내더군요. 그냥 'clisp.exe' 파일에 대해서 직접 단축아이콘 하나 만드시면 됩니다. 그리고, 어차피 Emacs 내에서 SLIME mode를 통해 실행할 것이기 때문에 단축아이콘을 쓸 일이 거의 없을 겁니다. 이 글에서는 'C:\CLISP' 폴더에 압축을 풀었다고 가정합니다.

3. EmacsW32+Emacs 설치
이것 역시 설치가 매우 간단합니다. 설치 패키지 형태로 되어 있기 때문에 실행한 다음 next 버튼만 누르다보면 설치가 완료됩니다. 설치 중간에 설치 폴더를 변경하지 않았다면 'C:\Program Files\Emacs' 폴더에 설치가 되었을 겁니다.

4. SLIME mode 설치 및 설정
Emacs 설치 폴더 아래에 만들어진 'site-lisp' 폴더에 'slime-2.0.zip' 파일의 압축을 풉니다. 그러면 'slime-2.0' 폴더가 만들어집니다. 이것으로 설치는 끝입니다. 이제 SLIME mode가 Emacs에서 load 될 수 있도록 '.emacs' 설정 파일에 SLIME 관련 내용을 추가해주기만 하면 됩니다. '.emacs' 파일은 'C:\Documents and Settings\사용자 계정\Application Data' 폴더에 있습니다. 없다면 새로 하나 만들어 주세요.

다음은 제가 사용하고 있는 SLIME 설정 내용입니다.
전체 파일은 여기서 받으세요.
;; SLIME 설치된 폴더
(add-to-list 'load-path
"C:/Program Files/Emacs/site-lisp/slime-2.0/")
(require 'slime)
;; UTF-8 인코딩을 기본으로 사용 --> 한글 symbol 사용을 위해
(setq slime-net-coding-system 'utf-8-unix)
;; Lisp 실행 파일
(setq inferior-lisp-program "C:/CLISP/clisp.exe")
(setq common-lisp-hyperspec-root
"http://www.lispworks.com/documentation/HyperSpec/")
;; FireFox를 사용한다면 아래 주석 해제
;(setq browse-url-generic-program
; "C:/Program Files/Mozilla Firefox/firefox.exe")
;(setq browse-url-browser-function (quote browse-url-generic))
(add-hook 'inferior-lisp-mode-hook
(lambda () (inferior-slime-mode t)))
(add-hook 'lisp-mode-hook
(lambda ()
(set (make-local-variable
'lisp-indent-function)
'common-lisp-indent-function)))
(slime-setup :autodoc t)

5. 실행해보기
자, 이제 실행을 해봅시다. Emacs를 실행한 다음 아래과 같이 입력합니다.

M-x slime

'M-x'는 'Alt'키를 누르면서 'x' 키를 누르라는 의미입니다. 그러면 창 가장 아래쪽 미니 버퍼에 커서가 깜빡이는데, 여기서 'slime'이라고 입력한 다음 enter 키를 누르면 됩니다. 이제 편집창에 새로운 버퍼들이 만들어지면서 뭔가 글이 막 올라가다가 마지막에 CLISP prompt가 뜨게 됩니다.

이 다음부터는 여러분의 몫입니다. ;-)

6. 재미있는 팁 한 가지를 알려드리면...
위 SLIME 설정 내용 중에 UTF-8 사용이 가능하도록 추가해준 부분이 있는데, 이렇게 UTF-8 인코딩을 사용하게 되면 한글 symbol을 사용할 수 있게 됩니다. 물론 사용하는 Lisp 구현체가 UTF-8을 지원해주어야 가능합니다. CLISP은 UTF-8을 지원하고 있습니다.

2007년 1월 8일 월요일

EmacsW32 - Enhancements for Emacs W32 Users


Unix 계열 환경에서 프로그램을 작성하거나 Lisp 프로그램을 주로 작성하는 사람이 아니라고 해도 Emacs라는 이 위대한 editor(사실 editor 그 이상이죠.)에 대한 이름은 한 번쯤 들어보셨을 것이라 생각됩니다. - Emacs에 대한 상세한 소개는 이미 잘 만들어져 있는 Wikipedia의 이맥스 페이지를 참고해주세요. -

저는 성격 상 Emacs보다는 vi 쪽으로 더 많은 정이 가지만, 요즘 들어서 Common Lisp을 공부하다 보니 Emacs만한 것이 없다는 생각이 절로 드네요. 그래서, Windows 환경에서 쓸만한 Emacs 패키지를 찾아보았습니다. EmacsWiki라든가 EmacsKR 같은 Emacs 커뮤니티 사이트를 뒤지다 보니 많은 분들이 추천하는 패키지가 딱 있더군요. 바로 EmacsW32입니다.

EmacsW32 자체는 Emacs lisp 모듈과 Emacs를 위한 유용한 Windows 프로그램을 모아 놓은 것입니다. 그런데, 친절하게도 현재 한창 개발 중인 Emacs 22 버전을 CVS 저장소에서 직접 가져다가 Windows 환경을 위한 몇 가지 유용한 patch까지 가미해서 설치 패키지 형태(EmacsW32+Emacs)로 제공해주고 있습니다. 이 설치 패키지는 기본적으로 leim을 포함하고 있어서 별도의 추가 설치 없이 바로 한글을 입력할 수 있고, Unicode 파일에 대한 편집도 가능하더군요. 몇 년 전에 잠시 사용해본 Emacs for Windows NT보다 훨씬 간편하고 안정적이라고 할 수 있었습니다.

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

LINK: http://ourcomments.org/Emacs/EmacsW32.html

Windows 환경에서 간편하게 사용할 수 있는 Emacs 패키지를 찾고 계신다면 EmacsW32+Emacs를 강력히 추천합니다. 그리고, Common Lisp 개발자인 경우 SLIME mode를 설치하시면 금상첨화입니다. :-)

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