아래는 GNU CLisp 로 실행한 것인데. Clozure CL 로 실행해도 거의 같은 결과를 얻는다.

명령프롬프트> clisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

[1]> (setf x #c(1 (/ 2.0 3.0))

*** - READ from
       #<INPUT CONCATENATED-STREAM #<INPUT STRING-INPUT-STREAM>
         #<IO TERMINAL-STREAM>>
      : bad syntax for complex number: #C(1 (/ 2.0 3.0))
The following restarts are available:
ABORT          :R1      Abort main loop
Break 1 [2]> (setf z (complex 1 (/ 2.0 3.0)))
#C(1 0.6666667)
Break 1 [2]> (setf y (/ 2.0 3.0))
0.6666667
Break 1 [2]> (setf z (complex 1 y))
#C(1 0.6666667)
Break 1 [2]> z
#C(1 0.6666667)
Break 1 [2]> (setf z (complex 1 (/ 2.0 3)))
#C(1 0.6666667)
Break 1 [2]> (setf z (- (complex 1 (/ 2.0 3))))
#C(-1 -0.6666667)
Break 1 [2]> z
#C(-1 -0.6666667)
Break 1 [2]> (realpart z)
-1
Break 1 [2]> (imagpart z)
-0.6666667
Break 1 [2]> (conjugate z)
#C(-1 0.6666667)
Break 1 [2]> (- z)
#C(1 0.6666667)
Break 1 [2]> (1- z)
#C(-2 -0.6666667)
Break 1 [2]> (1+ z)
#C(0 -0.6666667)
Break 1 [2]> (zerop z)
NIL
Break 1 [2]> (zerop (- z z))
T
Break 1 [2]> (zerop (+ z (- z)))
T
Break 1 [2]> (abs z)
1.2018504
Break 1 [2]> (sqrt z)
#C(0.31768727 -1.0492499)
Break 1 [2]> (zerop (+ z (- z)))
T
Break 1 [2]> (* z (conjuate z))

*** - EVAL: undefined function CONJUATE
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (FDEFINITION 'CONJUA
TE).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (FDEFINITION 'CONJUATE).
ABORT          :R4      Abort debug loop
ABORT          :R5      Abort main loop
Break 2 [3]> (* z (conjugate z))
#C(1.4444444 0.0)
Break 2 [3]> (defun distance-from-origin(z)
                          (realpart (sqrt (* z (conjugate z)))))
DISTANCE-FROM-ORIGIN
Break 2 [3]> (distance-from-origin z)
1.2018504
Break 2 [3]> ((distance-from-origin z) (abs z))

*** - EVAL: (DISTANCE-FROM-ORIGIN Z) is not a function name; try using a
      symbol instead
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead.
ABORT          :R2      Abort debug loop
ABORT          :R3      Abort debug loop
ABORT          :R4      Abort main loop
Break 3 [4]> (= (distance-from-origin z) (abs z))
T
Break 3 [4]> (- (distance-from-origin z) (abs z))
0.0
Break 3 [4]> (= (distance-from-origin z) (sqrt (+ (* (realpart z)
 (realpart z)) (* (imagpart z) (imagpart z)))))
T
Break 3 [4]>  (- (distance-from-origin z) (sqrt (+ (* (realpart z)
 (realpart z)) (* (imagpart z) (imagpart z)))))
0.0
Break 3 [4]> (sin z)
#C(-1.0354936 -0.38748237)
Break 3 [4]> (cos z)
#C(0.66488284 -0.60346806)
Break 3 [4]> (tan z)
#C(-0.56391037 -1.0946053)
Break 3 [4]> (asin z)
#C(-0.8048969 -0.85406184)
Break 3 [4]> (acos z)
#C(2.3756933 0.85406184)
Break 3 [4]> (atan z)
#C(-0.89473265 -0.30594388)
Break 3 [4]> (sinh z)
#C(-0.92357564 -0.9541945)
Break 3 [4]> (cosh z)
#C(1.2126874 0.72670895)
Break 3 [4]> (tanh z)
#C(-0.9072973 -0.2431405)
Break 3 [4]> (asinh z)
#C(-0.9614137 -0.4609276)
Break 3 [4]> (acosh z)
#C(0.8540618 -2.375693)
Break 3 [4]> (atanh z)
#C(-0.5756463 -0.94627345)
Break 3 [4]> (log z)
#C(0.1838624 -2.55359)
Break 3 [4]> (exp z)
#C(0.28911176 -0.22748554)
Break 3 [4]> (log (exp z))
#C(-1.0 -0.6666667)
Break 3 [4]> (exp (log z))
#C(-1.0 -0.6666667)
Break 3 [4]> (expt 2 z)
#C(0.44755954 -0.22291358)
Break 3 [4]> (expt z 2)
#C(0.5555555 1.3333334)
Break 3 [4]> (* z z)
#C(0.5555555 1.3333334)
Break 3 [4]> (quit)
Bye.

 

Posted by Scripter
,

Commonn Lisp 언어는 S-신택스라고 불리우는 구문 즉,

       (함수명 파라미터1 파라미터2 ... 파라미터n)

 인 형태의 구문을 사용한다. 예를 들어 뺄셈을 할 때에도

      (- 2 3 5 7)

라는 구문은 수학식 2 - 3 - 5 - 7 을 계산한 결과를 얻는다.



* CLisp  용 소스 파일: first-sample-2.lsp
#!/usr/bin/env clisp

;; 파일명: first-sample-2.lsp


(defun lg(x):
    (/ (log x) (log 2)) )
   
(defun log10(x):
    (/ (log x) (log 10)) )
   
(format t "이 소스는 CLisp 를 이용하여 실행됨!~%")
(format t "----------------~%")
(format t "수학식 계산하기:~%")
(format t "----------------~%")
(format t "pi + e = (+ pi (exp 1)) = ~A~%" (+ pi (exp 1)))
(format t "pi * e = (* pi (exp 1)) = ~A~%" (* pi (exp 1)))
(format t "sqrt(pi) + sqrt(e) = (+ (sqrt pi) (sqrt (exp 1))) = ~A~%" (+ (sqrt pi) (sqrt (exp 1))))
(format t "sqrt(pi + e) = (sqrt (+ pi (exp 1))) = ~A~%" (sqrt (+ pi (exp 1))))
(format t "sqrt(pi) - sqrt(e) = (- (sqrt pi) (sqrt (exp 1))) = ~A~%" (- (sqrt pi) (sqrt (exp 1))))
(format t "sqrt(pi - e) = ~A~%" (sqrt (- pi (exp 1))))
(format t "sin(pi) = (sin pi) = ~A~%" (sin pi))
(format t "cos(pi) = (cos pi = ~A~%" (cos pi))
(format t "tan(pi) = (tan pi) = ~A~%" (tan pi))
(format t "ln(e) = (log (exp 1)) = ~A~%" (log (exp 1)))
(format t "(lg 2) = (log2 2) = ~A~%" (lg 2))
(format t "(log10 (/ 1.0 10)) = ~A~%" (log10 (/ 1.0 10)))
(format t "pow(2, 10) = (expt 2 10) = ~A~%" (expt 2 10))
(format t "pow(2, 100) = (expt 2 10) = ~A~%" (expt 2 100))
(format t "pow(2, 1000) = (expt 2 1000) = ~A~%" (expt 2 1000))
(format t "len(str(pow(2, 1000))) = ~A = ~A~%" "(length (format nil \"~A\" (expt 2 100000)))" (length (format nil "~A" (expt 2 100000))))


 


* 실행 결과:


이 소스는 CLisp 를 이용하여 실행됨!
----------------
수학식 계산하기:
----------------
pi + e = (+ pi (exp 1)) = 5.8598742
pi * e = (* pi (exp 1)) = 8.539734
sqrt(pi) + sqrt(e) = (+ (sqrt pi) (sqrt (exp 1))) = 3.421175
sqrt(pi + e) = (sqrt (+ pi (exp 1))) = 2.4207177
sqrt(pi) - sqrt(e) = (- (sqrt pi) (sqrt (exp 1))) = 0.123732634
sqrt(pi - e) = 0.6506235
sin(pi) = (sin pi) = -5.0165576136843360246L-20
cos(pi) = (cos pi = -1.0L0
tan(pi) = (tan pi) = 5.0165576136843360246L-20
ln(e) = (log (exp 1)) = 0.99999994
(lg 2) = (log2 2) = 1.0
(log10 (/ 1.0 10)) = -1.0
pow(2, 10) = (expt 2 10) = 1024
pow(2, 100) = (expt 2 10) = 1267650600228229401496703205376
pow(2, 1000) = (expt 2 1000) = 1071508607186267320948425049060001810561404811705
53360744375038837035105112493612249319837881569585812759467291755314682518714528
56923140435984577574698574803934567774824230985421074605062371141877954182153046
47498358194126739876755916554394607706291457119647768654216766042983165262438683
7205668069376
len(str(pow(2, 1000))) = (length (format nil "~A" (expt 2 100000))) = 30103


 

 

Posted by Scripter
,

다항식 p(x) 를 1차 다항식 ax - b 로 나눌 때의 몫과 나머지를 구하는 조립제법을
Python 언어로 구현해 보았다. 조립제법은 일명 Horner의 방법이라고도 불리우는데, 이는
x = a 에서 다항식 p(x)의 값 p(a)을 계산하는 가장 빠른 알고리즘이기도 하다.

         p(x) = (ax - b)q(x) + r

여기서 r은 나머지이며 r = p(b/a) 이다. 또 q(x)는 몫이다.

[참고]
    * 온라인으로 조립제법 표 만들기 손으로 계산하는 조립제법 표 
    * 온라인으로 구하는 다항식의 도함수: 조립제법을 이용한 다항식의 도함수


아래의 소스파일은 이전에 작성했던 파일 testSyntheticDivision.lsp 를 수정한 것이다.

  1. ;;  Filename: testSyntheticDivision2.lsp
  2. ;;
  3. ;;  Purpose:  Find the quotient and remainder when some polynomial is
  4. ;;            divided by a monic polynomial of the first degree.
  5. ;;
  6. ;;  Execute:  clisp testSyntheticDivision2.lsp 5 -4 7 8 6 8
  7. ;;
  8. ;;  Date: 2013. 9. 7.
  9. ;; 사용법 표시
  10. (defun printUsage()
  11.     (format t "사용법: clisp testSyntheticDivision2.lsp [제식의 계수] [피제식의 계수들]~%")
  12.     (format t "조립제법(synthetic method)에 의한 다항식 나눗셈 결과를 보여준다.~%")
  13. )
  14. ;; 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  15. ;; 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  16. (defun simplify(v &optional width)
  17.     (let* ((tt "")
  18.            (slen 0))
  19.         (setf tt (format nil "~A" v))
  20.         (setf slen (length tt))
  21.         (if (and (>= slen 2) (string= (substring tt (- slen 2) slen) ".0"))
  22.             (setf tt (substring tt 0 (- slen 2))) )
  23.         (setf slen (length tt))
  24.         (if width
  25.             (if (< slen width)
  26.                 (setf tt (concatenate 'string (make-string (- width slen) :initial-element #\Space) tt)) ))
  27.         tt
  28.     )
  29. )
  30. ;; "/수" 표시하기
  31. ;; 부동소수점수의 표현이 .0 으로 끝나는 경우 이를 잘라낸다.
  32. ;; 전체 문자열 표시 너비는 매개변수 width 로 전달받아 처리한다.
  33. (defun simplifyReciprocal(v &optional width)
  34.     (let* ((tt "")
  35.            (tlen 0))
  36.         (setf tt (format nil "/~A" v))
  37.         (setf tlen (length tt))
  38.         (if (and (>= tlen 2) (string= (substring tt (- tlen 2) tlen) ".0"))
  39.             (setf tt (substring tt 0 (- tlen 2))) )
  40.         (setf tlen (length tt))
  41.         (if width
  42.             (if (< tlen width)
  43.                 (setf tt (concatenate 'string (make-string (- width tlen) :initial-element #\Space) tt)) ))
  44.         tt
  45.     )
  46. )
  47. ;; 다항식을 내림차순의 스트링 표현으로 반환
  48. (defun toPolyString(c)
  49.     (let* ((ttt "")
  50.            (sc0 "")
  51.            (sc "")
  52.            (k 0))
  53.         (setf ttt "")
  54.         (setf sc0 (simplify (nth 0 c) nil ))
  55.         (if (> (length c) 2)
  56.             (cond
  57.                ((string= sc0 "1") (setf ttt (concatenate 'string ttt (format nil "x^~D" (- (length c) 1)))))
  58.                ((string= sc0 "-1") (setf ttt (concatenate 'string ttt (format nil "-x^~D" (- (length c) 1)))))
  59.                (t (setf ttt (concatenate 'string ttt sc0 (format nil " x^~D" (- (length c) 1)))))
  60.             )
  61.         )
  62.         (if (= (length c) 2)
  63.             (cond
  64.                ((string= sc0 "1") (setf ttt (concatenate 'string ttt "x")))
  65.                ((string= sc0 "-1") (setf ttt (concatenate 'string ttt "-x")))
  66.                (t (setf ttt (concatenate 'string ttt sc0 " x")))
  67.             )
  68.         )
  69.         (if (= (length c) 1)
  70.                (setf ttt (concatenate 'string ttt sc0))
  71.         )
  72.         (loop for i from 1 below (length c) do
  73.             (setf k (- (length c) 1 i))
  74.             (setf sc (simplify (nth i c) nil))
  75.             (if (> k 1) (progn
  76.                 (cond
  77.                     ((> (nth i c) 0.0)
  78.                         (if (string= sc "1")
  79.                             (setf ttt (concatenate 'string ttt " + " (format nil "x^~D" k)))
  80.                             (setf ttt (concatenate 'string ttt " + " sc (format nil " x^~D" k)))
  81.                         ) )
  82.                     ((< (nth i c) 0.0)
  83.                         (if (string= sc "-1")
  84.                             (setf ttt (concatenate 'string ttt " - " (format nil "x^~D" k)))
  85.                             (setf ttt (concatenate 'string ttt " - " (simplify (abs (nth i c)) nil) (format nil " x^~D" k)))
  86.                         ) )
  87.                     )
  88.                 )
  89.             )
  90.             (if (= k 1)
  91.                 (cond
  92.                     ((> (nth i c) 0.0)
  93.                         (if (string= sc "1")
  94.                             (setf ttt (concatenate 'string ttt " + " "x"))
  95.                             (setf ttt (concatenate 'string ttt " + " sc " x"))
  96.                         ) )
  97.                     ((< (nth i c) 0.0)
  98.                         (if (string= sc "-1")
  99.                             (setf ttt (concatenate 'string ttt " - " "x"))
  100.                             (setf ttt (concatenate 'string ttt " - " (simplify (abs (nth i c))) " x"))
  101.                         ) )
  102.                 )
  103.             )
  104.             (if (= k 0)
  105.                 (cond
  106.                     ( (> (nth i c) 0.0) (setf ttt (concatenate 'string ttt " + " sc)) )
  107.                     ( (< (nth i c) 0.0) (setf ttt (concatenate 'string ttt " - " (simplify (abs (nth i c))) )) )
  108.                 )
  109.             )
  110.         )
  111.         ttt
  112.     )
  113. )
  114. ;; 다항식 나눗셈 결과를
  115. ;;     (피제식) = (제식)(몫) + (나머지)
  116. ;; 형태로 출력
  117. (defun printDivisionResult(a c d b)
  118.     (let* ((strLine ""))
  119.         (setf strLine (concatenate 'string "  " (toPolyString c)))
  120.         (format t "~A~%" strLine)
  121.         (setf strLine (concatenate 'string "    = ( " (toPolyString (list (nth 0 a) (- (nth 1 a)))) " )"))
  122.         (setf tmp (make-list (- (length b) 1) :initial-element 0.0)) 
  123.         (loop for i from 0 below (length tmp) do
  124.             (setf (nth i tmp) (nth i b)) )
  125.         (setf strLine (concatenate 'string strLine "( " (toPolyString tmp) " )"))
  126.         (setf r (nth (- (length d) 1) d))
  127.         (cond
  128.            ((> r 0.0)  (setf strLine (concatenate 'string strLine " + " (simplify r nil) )))
  129.            ((< r 0.0)  (setf strLine (concatenate 'string strLine " - " (simplify (abs r) nil) )))
  130.         )
  131.         (format t "~A~%" strLine)
  132.     )
  133. )
  134. ;; 조립제법 계산표 출력 함수
  135. (defun printSyntheticTable(a c s d q)
  136.     (let* ((strLine ""))
  137.         (setf strLine "         | ")
  138.         (setf strLine (concatenate 'string strLine (simplify (nth 0 c) 10) ))
  139.         (loop for i from 1 below (length c) do
  140.             (setf strLine (concatenate 'string strLine "  " (simplify (nth i c) 10) )))
  141.         (format t "~A~%" strLine)
  142.         (setf strLine (concatenate 'string (simplify (nth 1 a) 8) " |"))
  143.         (setf strLine (concatenate 'string strLine "             "))
  144.         (setf strLine (concatenate 'string strLine (simplify (nth 1 s) 10)))
  145.         (loop for i from 2 below (length s) do
  146.             (setf strLine (concatenate 'string strLine "  " (simplify (nth i s) 10) )))
  147.         (format t "~A~%" strLine)
  148.         (setf strLine "         |")
  149.         (loop for i from 0 below (length q) do
  150.             (setf strLine (concatenate 'string strLine "------------")))
  151.         (format t "~A~%" strLine)
  152.         (setf strLine "         | ")
  153.         (setf strLine (concatenate 'string strLine (simplify (nth 0 d) 10)))
  154.         (loop for i from 1 below (length d) do
  155.             (setf strLine (concatenate 'string strLine "  " (simplify (nth i d) 10))))
  156.         (format t "~A~%" strLine)
  157.         (setf strLine (concatenate 'string (simplifyReciprocal (nth 0 a) 8) " | "))
  158.         (setf strLine (concatenate 'string strLine (simplify (nth 0 q) 10)))
  159.         (loop for i from 1 below (1- (length q)) do
  160.             (setf strLine (concatenate 'string strLine "  " (simplify (nth i q) 10) )))
  161.         (format t "~A~%" strLine)
  162.     )
  163. )
  164. ;; 실행 시작 지점
  165. (if (< (length ext:*args*) 3) (progn
  166.     (printUsage)
  167.     (quit) ))
  168. ;; ----------------------------------------------------
  169. ;; 피제식은 c_0 x^n +  c_1 x^(n -1) + ... + c_n
  170. ;; 제식은 a x -  b
  171. (setf a (list (read-from-string (nth 0 ext:*args*)) (- (read-from-string (nth 1 ext:*args*)))) )
  172. (setf c (make-list (- (length ext:*args*) 2) :initial-element 0.0) )
  173. (setf s (make-list (- (length ext:*args*) 2) :initial-element 0.0) )
  174. (setf d (make-list (- (length ext:*args*) 2) :initial-element 0.0) )
  175. (setf b (make-list (- (length ext:*args*) 2) :initial-element 0.0) )
  176. (loop for i from 0 below (length c) do
  177.     (setf (nth i c) (read-from-string (nth (+ i 2) ext:*args*))))
  178. ;; ----------------------------------------------------
  179. ;; 조립제법의 주요 부분
  180. (setf (nth 0 s) 0.0)
  181. (setf (nth 0 d) (nth 0 c))
  182. (setf (nth 0 b)  (+ 0.0 (/ (nth 0 c) (nth 0 a))))
  183. (loop for i from 1 below (length c) do
  184.     (setf (nth i s) (* (nth (- i 1) b) (nth 1 a)))
  185.     (setf (nth i d) (+ (nth i c) (nth i s)))
  186.     (setf (nth i b) (+ 0.0 (/ (nth i d) (nth 0 a)))) )
  187. ;; ----------------------------------------------------
  188. ;; 몫의 계수와 나머지를 출력한다.
  189. (format t "몫의 계수는 ")
  190. (loop for i from 0 below (- (length b) 2) do
  191.     (format t (concatenate 'string (simplify (nth i b)) ",  ")))
  192. (format t (concatenate 'string (simplify (nth (- (length b) 2) b)) " "))
  193. (format t (concatenate 'string "이고, 나머지는 " (simplify (nth (- (length d) 1) d)) " 이다.~%"))
  194. (terpri)
  195. ;; ----------------------------------------------------
  196. ;; 조립제법 표를 출력한다.
  197. (printSyntheticTable a c s d b)
  198. (terpri)
  199. ;; ----------------------------------------------------
  200. ;; (피제식) = (제식) x (몫) + (나머지)
  201. (printDivisionResult a c d b)
  202. (format t "~%")




실행> clisp testSyntheticDivision2.lsp 5 -4 7 8 6 8

몫의 계수는 1.4, 2.72, 3.3760002 이고, 나머지는 21.504002 이다. | 7 8 6 8 4 | 5.6 10.88 13.504001 |------------------------------------------------ | 7 13.6 16.880001 21.504002 /5 | 1.4 2.72 3.3760002 7 x^3 + 8 x^2 + 6 x + 8 = ( 5 x - 4 )( 1.4 x^2 + 2.72 x + 3.3760002 ) + 21.504002

 

 

Posted by Scripter
,

Common Lisp 언어로 숫자 맞추기 게임을 작성해 보았다.

아래 소스의 18째 줄 (setf guess (parse-integer sbuf)) 는 스트링을 정수로 변환하는 과정이다.



소스 파일명: guessNumber01.lsp

  1. #!/usr/bin/env clisp
  2. ;;   Filename: guessNumber01.lsp
  3. ;;   Purpose:  Interatice game guessing a given number.
  4. ;;                 (if condition
  5. ;;                     (........)    ; when condition is true
  6. ;;                     (........)    ; when condition is flase
  7. ;;                 )
  8. ;;   Execute: clisp guessNumber01.lsp
  9. ;;                     ......
  10. ;;   Date: 2013. 9. 7.
  11. (defun doGuessing(num)
  12.     (let* ((sbuf "")
  13.            (guess 0))
  14.         (format t "Enter your guess:~%")
  15.         (setf sbuf (read-line))
  16.         (setf guess (parse-integer sbuf))
  17.         (if (= guess num)
  18.             (progn
  19.                 (format t "You win!~%")
  20.                 (quit)
  21.             )
  22.         )
  23.         ;; we won't get here if (= guessnum)
  24.         (if (< guess num)
  25.             (progn
  26.                 (format t "Too low!~%")
  27.                 (doGuessing num)
  28.             )
  29.             (progn
  30.                 (format t "Too high!~%")
  31.                 (doGuessing num)
  32.             )
  33.         )
  34.     )
  35. )
  36. (doGuessing 123)




실행> clisp guessNumber01.lsp
Enter your guess:
111
Too low!
Enter your guess:
222
Too high!
Enter your guess:
123
You win!



Posted by Scripter
,


[파일명:  testStringFindInList.lsp]------------------------------------------------
(defun my-find(arr s)
    (let ((k -1)
          (r -1))
        (loop for i from 0 below (length arr) do
            (setf k (search s (nth i arr)))
            (if k (progn (setf r i) (return i)))
        )
        r
    )
)

(defun printList(arr)
    (format t "[")
    (loop for i from 0 below (1- (length arr)) do
        (format t "~A, " (nth i arr))
    )
    (if (plusp (length arr))
        (format t "~A" (nth (1- (length arr)) arr))
    )
    (format t "]~%")
)

(setf words (list "하나" "둘" "셋" "넷" "다섯" "여섯"))

(format t "list: ")
(printList words)
(setf w (my-find words "셋"))
(if (>= w 0)
    (progn
        (format t "발견!  ~%")
        (format t "Next word of 셋 in list: ~A~%" (nth (1+ w) words))
    )
)

(format t "Sorting...~%")
(sort words #'string<)

(format t "list: ")
(printList words)
(setf w (my-find words "셋"))
(if (>= w 0)
    (progn
        (format t "발견!  ~%")
        (format t "Next word of 셋 in list: ~A~%" (nth (1+ w) words))
    )
)
------------------------------------------------


실행> clisp testStringFindInList.lsp
list: [하나, 둘, 셋, 넷, 다섯, 여섯]
발견!  Next word of 셋 in list: 넷
Sorting...
list: [넷, 다섯, 둘, 셋, 여섯, 하나]
발견!  Next word of 셋 in list: 여섯



Posted by Scripter
,

[파일명:  testSort.lsp]------------------------------------------------
(defun printArray(a)
    (format t "[")
    (loop for i from 0 below (1- (length a)) do
        (format t "~A, " (nth i a))
    )
    (if (plusp (length a))
        (format t "~A" (nth (1- (length a)) a))
    )
    (format t "]~%")
)


(setf list ext:*args*)
(sort list #'string<)
(printArray list)
------------------------------------------------


실행> clisp testSort.lsp one two three four five
[five, four, one, three, two]

실행> clisp testSort.lsp 하나 둘 셋 넷 다섯
[넷, 다섯, 둘, 셋, 하나]




Posted by Scripter
,

정의 (소수와 합성수)
    1보다 큰 양의 정수 n에 대하여
    (i) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하면,
        n을 합성수(合成數, composite number)라고 한다. 참고로 이 경우,
        a, b 중에 적어도 하나는 sqrt(n) 보다 작거나 같다.
        합성수의 예로는 4, 6, 9, 24, 143 등이 있다.
    (ii) n = a * b 를 만족하고 1보다 큰 두 양의 정수 a와 b가 존재하지 않으면,
         즉 n을 두 양의 정수의 곱으로 표현하는 방법이 1*n과 n*1 두 가지 뿐이면,
         n을 소수(素數, prime number)라고 한다.  소수의 예로는 2, 3, 5, 7, 11 등이 있다.
         n이 소수인지 아닌지 확인하려면, 
         n을 2 보다 크거나 같고 sqrt(n) 보다 작거나 같은 모든 정수로 나누어 본다.
         이 경우 언제나 나누어 떨어지지  않으면 n은 소수이고, 그렇지 않으면 n은 합성수이다.
    

우선 다음의 Common Lisp 소스 코드는 명령행 인자로 전달 받은 양의 정수 n을
2 및 3, 5, 7, ... , (sqrt n) 이하의 홀수들로 나누어 보아 n이 합성수인지 아닌지
확인하는 애플리케이션 소스이다. 확인하는데 걸린 경과 시간도 알려준다.

;;  Filename: divideEach.lsp
;;
;;  Purpose:  Determine whether the given integer is a prime or not.
;;
;;  Execute: clisp divideEach.lsp [integer]
;;
;;     Date:  2013. 9. 6.

#|
  Execution Examples:
      Prompt> clisp divideEach.lsp 1234567812343
      1234567812343 = 1 * 1234567812343
      1234567812343 is a prime.
      Elapsed time: 3 secs
 
      Prompt> clisp divideEach.lsp 9999994200000841
      9999994200000841 = 99999971 * 99999971
      9999994200000841 is a not prime
      Elapsed time: 51.437000 sec
 
      Prompt> clisp divideEach.lsp 18446744073709551617
      18446744073709551617 = 274177 * 67280421310721
      18446744073709551617 is a not prime
      Elapsed time: 0.141000 sec

      Prompt> clisp divideEach.lsp 10023859281455311421
      10023859281455311421 = 1308520867 * 7660450463
      10023859281455311421 is a not prime
      Elapsed time: 705.016000 sec
|#


(setf n 10006099720301)
(if (> (length ext:*args*) 0)
    (setf n (parse-integer (nth 0 ext:*args*)))
)

(setf z (floor (/ n 2)))
(if (= n (* 2 z))
    (progn
        (format t "~A = ~A * ~A~d" n 2 z)
        (quit)
    )
)

(setf time1 (get-universal-time))

(setf d 1)
(setf k 3)

(loop while (<= (* k k) n) do
    (setf z (floor (/ n k)))
    (if (= n (* k z))
        (progn
            (set d k)
            (return)
        )
    )
    (setf k (+ k 2))
)

(setf z (floor (/ n d)))

(setf time2 (get-universal-time))

(format t "~A = ~A * ~A~%" n d (floor (/ n d)))

(if (= d 1)
    (format t "~A is a prime.~%" n)
    (format t "~A is a not prime.~%" n)
)

(format t "Elapsed time: ~A secs" (- time2 time1))

 




이제 다음은 정수의 인수분해 능력이 뛰어난  Pollard의 rho 방법(일명 거북이와 토끼 알고리즘, tortoise-hair algorithm)을 구현한  Common Lisp 소스 코드이다. 이 알고리즘은 소수에 대해서는 시간이 많이 걸리지만, 합성수에 대해서는 시간이 매우 적게 걸린다는 것이 특징이다.

 

;;  Filename: pollardRho.lsp
;;
;;  Purpose:  By using the pollard rho method,
;;            determine whether the given integer is a prime or not.
;;
;;      See:  http://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
;;            http://en.wikipedia.org/wiki/Floyd%27s_cycle-finding_algorithm#Tortoise_and_hare#
;;
;;  Execute: clisp pollardRho.lsp [integer]
;;
;;     Date:  2013. 9. 6.

#|
  Execution Examples:
      Prompt> clisp pollardRho.lsp 1234567812343
      Try first the Pollard rho algorithm with c = 2
      d = 1234567812343, count = 466951
      Try second the Pollard rho algorithm with c = 3
      d = 1, count = 1111112
      Try third the Pollard rho algorithm with c = 1
      d = 1234567812343, count = 799441
      1234567812343 = 1 * 1234567812343
      Elapsed time: 104 secs      Try first the Pollard rho algorithm with c = 2

      Prompt> clisp pollardRho.lsp 9999994200000841
      Try first the Pollard rho algorithm with c = 2
      d = 99999971, count = 3593
      9999994200000841 = 99999971 * 99999971
      Elapsed time: 0 secs

      Prompt> clisp pollardRho.lsp 18446744073709551617
      Try first the Pollard rho algorithm with c = 2
      d = 274177, count = 1028
      18446744073709551617 = 274177 * 67280421310721
      Elapsed time: 0 secs

      Prompt> clisp pollardRho.lsp 10023859281455311421
      Try first the Pollard rho algorithm with c = 2
      d = 1308520867, count = 20350
      10023859281455311421 = 1308520867 * 7660450463
      Elapsed time: 1 secs
|#


(defun f(x c n)
    (floor (mod (+ (* x x) c) n))
)

(defun g(x c n)
    (f (f x c n) c n)
)

(defun  my-gcd(x y):
 (let* ((a (abs x))
        (b (abs y))
        (tt 0))
        (if (zerop b) a)
        (loop while (not (zerop b)) do
            (setf tt (floor (mod a b)))
            (setf a b)
            (setf b tt)
        )
        a
    )
)

(defun pollardRho(n)
 (let* ((c 2)
        (x 1)
        (y 1)
        (d 1)
        (savedX x)
        (count 0)
        (tt 0))

     (setf c 2)
     (setf x 1)
        (setf y 1)
     (setf d 1)
     (setf savedX x)
     (setf count 0)

        (format t "Try first the Pollard rho algorithm with c = ~A~%" c)
        (loop while (and (= d 1) (<= (* count count) n)) do
            (setf x (f x c n))
            (if (= x savedX)
                (progn
                    (format t "It is cyclic.  x = ~A~%" x)
                    (return)   ;; break loop
                )
            )
            (setf y (g y c n))
            (setf d (my-gcd (abs (- x y)) n))
            (setf count (1+ count))
        )

        (format t "d = ~A, count = ~A~%" d count)
        (if (and (> d 1) (< d n))
                d
      (progn
     (setf c 3)
     (setf x 1)
        (setf y 1)
     (setf d 1)
     (setf savedX x)
     (setf count 0)

        (format t "Try second the Pollard rho algorithm with c = ~A~%" c)
        (loop while (and (= d 1) (<= (* count count) n)) do
            (setf x (f x c n))
            (if (= x savedX)
                (progn
                    (format t "It is cyclic.  x = ~A~%" x)
                    (return)   ;; break loop
                )
            )
            (setf y (g y c n))
            (setf d (my-gcd (abs (- x y)) n))
            (setf count (1+ count))
        )

        (format t "d = ~A, count = ~A~%" d count)
        (if (and (> d 1) (< d n))
                d

      (progn
     (setf c 1)
     (setf x 1)
        (setf y 1)
     (setf d 1)
     (setf savedX x)
     (setf count 0)

        (format t "Try third the Pollard rho algorithm with c = ~A~%" c)
        (loop while (and (= d 1) (<= (* count count) n)) do
            (setf x (f x c n))
            ; (format t "  x = ~A~%" x)
            (if (= x savedX)
                (progn
                    (format t "It is cyclic.  x = ~A~%" x)
                    (return)   ;; break loop
                )
            )
            (setf y (g y c n))
            (setf d (my-gcd (abs (- x y)) n))
            (setf count (1+ count))
        )

        (format t "d = ~A, count = ~A~%" d count)
        (if (and (> d 1) (< d n))
                d

         1  )
      ))
      ))
    )
)


(setf n 9991)
(if (> (length ext:*args*) 0)
    (setf n (parse-integer (nth 0 ext:*args*)))
)

(setf time1 (get-universal-time))

(setf k (pollardRho n))

(setf time2 (get-universal-time))

(setf z (floor (/ n k)))
(if (= n (* k z))
    (format t "~A = ~A * ~A~%" n k z)
)

(format t "Elapsed time: ~A secs" (- time2 time1))

 

 

 

Posted by Scripter
,

초등학교 때 배우는 두 정수의 곱셈표를 만들어 주는 Common Lisp 소스이다.
(이 소스는 CLisp으로 잘 실행됨을 확인하였다.)

Common Lisp 언어로, 양의 정수 a를 양의 정수 b로 나는 몫을 구하려면

        (setf q (floor (/ a b)))

한다. 그 몫은 변수 q에 저장된다. 이렇게 하는 이유는

        (setf q (/ a b))

로 한 경우 q에는 분수 a/b가 저장되기 때문이다.

 

;;  Filename: makeMultTable.lsp
;;
;;     Print a multiplication table.
;;
;;     Execute: clisp makeMultTable.lsp 230 5100
;;
;;  Date: 2013, 9. 6.


(defun printUsing()
    (format t "Using: clisp makeMultTable.lsp [number1] [number2]~%")
    (format t "Print a multiplication table for the given two integers.~%")
)

(defun printMultTable(x y)
    (let* ((nx x)
           (ny y)
           (nz 0)
           (n  0)
           (y1  0)
           (ntail1 0)
           (ntail2 0)
           (strX "")
           (strY "")
           (strZ "")
           (strT "")
           (zeros  "0000000000000000000000000000000000000000")
           (whites "                                        ")
           (bars   "----------------------------------------")
           (loffset "       ")
           (line1 "")
           (line2 "")
           (line3 "")
           (line4 ""))
           
        (if  (minusp nx) (setf nx (- nx)))
        (if  (minusp ny) (setf ny (- ny)))

        (setf ntail1 0)
        (setf ntail2 0)
        (loop while (zerop (mod nx 10)) do
            (setf nx (floor (/ nx 10)))
            (setf ntail1 (1+ ntail1))
        )
        (loop while (zerop (mod ny 10)) do
            (setf ny (floor (/ ny 10)))
            (setf ntail2 (1+ ntail2))
        )

        (setf z (* nx ny))
        (setf strZ (format nil "~D" z))
        (setf strX (format nil "~D" nx))
        (setf strY (format nil "~D" ny))
        (setf n (length strY))

        (setf line4 (concatenate 'string loffset strZ))
        (setf line1 (concatenate 'string loffset (substring whites 0 (- (length strZ) (length strX))) strX))
        (setf line2 (concatenate 'string "   x ) " (substring whites 0 (- (length strZ) (length strY))) strY))
        (setf line3 (concatenate 'string "     --" (substring bars 0 (length strZ))))
        
        (format t "~A~A~%" line1 (substring zeros 0 ntail1))
        (format t "~A~A~%" line2 (substring zeros 0 ntail2))
        (format t "~A~%" line3)
        (if (> (length strY) 1)
            (progn
                (loop for i from 0 below (length strY) do
                    (setf y1 (parse-integer (substring strY (- (length strY) i 1) (- (length strY) i))))
                    (if (not (zerop y1))
                        (progn
                            (setf strT (format nil "~D" (* nx y1)))
                            (format t "~A~A~A~%" loffset (substring whites 0  (- (length strZ) (length strT) i)) strT)
                        )
                    )
                )
                (format t "~A~%" line3)
            )
        )

        (format t "~A~A~A~%" line4 (substring zeros 0 ntail1) (substring zeros 0 ntail2))
    )
)


(if (>= (length ext:*args*) 2)
    (progn
        (setf x (parse-integer (nth 0 ext:*args*)))
        (setf y (parse-integer (nth 1 ext:*args*)))
        (format t "~%")
        (printMultTable x y)
    )
    (printUsing)
)

 


실행> clisp makeMultTable.lsp 230 5100
결과>

         230
   x )   5100
     ------
         23
       115
     ------
       1173000

 

Posted by Scripter
,
▒ Common Lips 소스:  testStringReverse.lsp

#!/usr/bin/env clisp

(defun my-string-reverse (s)
    (let* ((arr (concatenate 'list s))
           (arr2 (reverse arr)))
        (format nil "~{~A~^~}" arr2)
    )
)

(setf s "Hello, world!")
(setf s2 "안녕하세요?")


(format t "s = ~A~%" s)
(format t "(reverse s) = ~A~%" (reverse s))
(format t "(my-string-reverse s) = ~A~%" (my-string-reverse s))
(format t "s2 = ~A~%" s2)
(format t "(reverse s2) = ~A~%" (reverse s2))
(format t "(my-string-reverse s2) = ~A~%" (my-string-reverse s2))

;; --------------------------------------------------------------
;; 출력 결과(CLisp 에서  MS949 인코딩으로 소스를 저장한 경우):
;;    s = Hello, world!
;;    (reverse s) = !dlrow ,olleH
;;    (my-string-reverse s) = !dlrow ,olleH
;;    s2 = 안녕하세요?
;;    (reverse s2) = ?요세하녕안
;;    (my-string-reverse s2) = ?요세하녕안




위의 예제에서 보듯이 CP949 한글의 문자열을 거꾸로 하기가 CLisp의 경우에는 잘 동작함이 확인되었다.
이를 대화형 모드(inttractive mode) CLisp에서 다시 한번 확인해 보자.

[CLisp의 대화형 모드에서 실행한 경우]---------------------
명령 프롬프트> clisp
 i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

[1]> (setf s "Hello, world!")
"Hello, world!"
[2]> (setf s2 "안녕하세요?")
"안녕하세요?"
[3]> (defun my-string-reverse (s)
    (let* ((arr (concatenate 'list s))
           (arr2 (reverse arr)))
        (format nil "~{~A~^~}" arr2)
    )
)
MY-STRING-REVERSE

Break 1 [7]> (format t "s = ~A~%" s)
s = Hello, world!
NIL
Break 1 [7]> (format t "(reverse s) = ~A~%" (reverse s))
(reverse s) = !dlrow ,olleH
NIL
Break 1 [7]> (format t "(my-string-reverse s) = ~A~%" (my-string-reverse s))
(my-string-reverse s) = !dlrow ,olleH
NIL
Break 1 [7]> (format t "s2 = ~A~%" s2)
s2 = 안녕하세요?
NIL
Break 1 [7]> (format t "(reverse s2) = ~A~%" (reverse s2))
(reverse s2) = ?요세하녕안
NIL
<-string-reverse s2) = ~A~%" (my-string-reverse s2))
(my-string-reverse s2) = ?요세하녕안
NIL
Break 1 [7]> (quit)
Bye.
----------------------------------------




Posted by Scripter
,

다음은 초등학교에서 배우는 나눗셈 계산표를 만들어주는 Common Lisp 소스 코드이다.
나눗셈 계산표를 완성하고 나서 약수, 배수 관계를 알려준다.

아래의 소스는 CLisp으로 실행되도록 작성되었다.

  1. #!/usr/bin/env clisp
  2. ;;  Filename: makeDivisionTable.lsp
  3. ;;
  4. ;;  Purpose:  Make a division table in a handy written form.
  5. ;;
  6. ;;  Execute: clisp makeDivisionTable.lsp 12345 32
  7. ;;           clisp makeDivisionTable.lsp 500210 61
  8. ;;           ./makeDivisionTable.lsp 500210 61
  9. ;;
  10. ;;     Date:  2013, 9. 5.
  11. (defun printUsage()
  12.     (format t "사용법: clisp makeDivisionTable.lsp [피제수] [제수]~%")
  13.     (format t "손으로 작성한 형태의 나눗셈 표를 만들어준다.~%") )
  14. (defun simplify(v &optional width)
  15.     (let* ((tt "")
  16.            (slen 0))
  17.         (setf tt (format nil "~A" v))
  18.         (setf slen (length tt))
  19.         (if (and (>= slen 2) (string= (substring tt (- slen 2) slen) ".0"))
  20.             (setf tt (substring tt 0 (- slen 2))) )
  21.         (setf slen (length tt))
  22.         (if width
  23.             (if (< slen width)
  24.                 (setf tt (concatenate 'string (make-string (- width slen) :initial-element #\Space) tt)) ))
  25.         tt
  26.     )
  27. )
  28. (defun getSuffix(v)
  29.     (let* ((tt (mod (abs v) 10))
  30.            (suffix "은"))
  31.         (if (search (format nil "~A" tt) "2459")
  32.             (setf suffix "는") )
  33.         suffix
  34.     )
  35. )
  36. (defun makeTable(numer denom quotient)
  37.     (let* ((strNumer (format nil "~A" numer))
  38.            (strDenom (format nil "~A" denom))
  39.            (strQuotient (format nil "~A" quotient))
  40.            (lenN (length strNumer))
  41.            (lenD (length strDenom))
  42.            (lenQ (length strQuotient))
  43.            (offsetLeft (+ 3 lenD 3))
  44.            (spaces (make-string 100 :initial-element #\Space))
  45.            (uline (make-string (+ lenN 2) :initial-element #\_))
  46.            (sline (make-string lenN :initial-element #\-))
  47.            (bias (- lenN lenQ))
  48.            (strTmpR (substring strNumer 0 (+ bias 1)))
  49.            (tmpR (parse-integer strTmpR))
  50.            (tmpSub 0)
  51.            (oneDigit nil) )
  52.         (format t "~A~A~A~%" (substring spaces 0 offsetLeft) (substring spaces 0 bias) (format nil "~D" quotient))
  53.         (format t "~A~A~%" (substring spaces 0 (- offsetLeft 2)) uline)
  54.         (format t "~A~A~A~A" "   " strDenom " ) " strNumer)
  55.         (loop for i from 0 below lenQ do
  56.             (if (string= (substring strQuotient i (1+ i)) "0")
  57.                 (progn
  58.                     (if (< (1+ i) lenQ)
  59.                         (progn
  60.                            (setf oneDigit (substring strNumer (+ bias i 1) (+ bias i 2)))
  61.                            (format t "~A" oneDigit)
  62.                            (setf strTmpR (concatenate 'string strTmpR oneDigit))
  63.                            (setf tmpR (parse-integer strTmpR))
  64.                         )
  65.                     )
  66.                 )
  67.                 (progn
  68.                     (format t "~%")
  69.                     (setf tmpSub (* (parse-integer (substring strQuotient i (1+ i))) denom))
  70.                     (format t "~A~A~%" (substring spaces 0 offsetLeft) (simplify tmpSub (+ bias i 1)))
  71.                     (format t "~A~A~%" (substring spaces 0 offsetLeft) sline)
  72.                     (setf tmpR (- tmpR tmpSub))
  73.                     (if (and (= tmpR 0) (< (+ i 1) lenQ))
  74.                         (format t "~A~A" (substring spaces 0 offsetLeft) (substring spaces 0 (+ bias i 1)))
  75.                         (format t "~A~A" (substring spaces 0 offsetLeft) (simplify tmpR (+ bias i 1)))
  76.                     ) 
  77.                     (setf strTmpR (format nil "~D" tmpR)) 
  78.                     (if (< (+ i 1) lenQ)
  79.                         (progn
  80.                             (setf oneDigit (substring strNumer (+ bias i 1) (+ bias i 2)))
  81.                             (if (plusp (length oneDigit))
  82.                                 (progn
  83.                                     (format t "~A" oneDigit)
  84.                                     (setf strTmpR (concatenate 'string strTmpR oneDigit))
  85.                                 )
  86.                             )
  87.                             (setf tmpR (parse-integer strTmpR))
  88.                         )
  89.                     )
  90.                 )
  91.             )
  92.         )
  93.         tmpR
  94.     )
  95. )
  96. ;; Begin here
  97. (if (< (length ext:*args*) 2)
  98.     (progn
  99.         (printUsage)
  100.         (quit)
  101.     )
  102. )
  103. (setf a nil)
  104. (setf b nil)
  105. (handler-case
  106.     (progn
  107.         (setf a (parse-integer (nth 0 ext:*args*)))
  108.         (setf b (parse-integer (nth 1 ext:*args*)))
  109.         (if (minusp a)
  110.             (progn
  111.                 (format t "피제수: ~A~%" a)
  112.                 (format t "피제수는 양의 정수라야 합니다.~%")
  113.                 (quit)
  114.             )
  115.             (if (minusp b)
  116.                 (progn
  117.                     (format t "제수: ~A~%" b)
  118.                     (format t "제수는 양의 정수라야 합니다.~%")
  119.                     (quit)
  120.                 )
  121.             )
  122.         )
  123.         (setf q (floor (/ a b)))
  124.         (setf r (mod a b))
  125.         (format t "나눗셈 ~A ÷ ~A 의 결과: " a b)
  126.         (format t "몫:  ~A, " q)
  127.         (format t "나머지: ~A~%" r)
  128.         (format t "~%")
  129.         (setf k (makeTable a  b q))
  130.         (format t "~%")
  131.         (if (= k r)
  132.             (format t "~%나머지: ~A~%" k)
  133.         )
  134.         (if (= k 0)
  135.             (progn
  136.                 (format t "~A = ~A x ~A~%" a b q)
  137.                 (format t "~A~A ~A의 배수(mupltiple)이다.~%" a (getSuffix a) b)
  138.                 (format t "~A~A ~A의 약수(divisor)이다.~%" b (getSuffix b) a)
  139.                 (format t "~%")
  140.             )
  141.             (progn
  142.                 (format t "~A = ~A x ~A + ~A~%" a b q r)
  143.                 (format t "~A~A ~A의 배수(mupltiple)가 아니다.~%" a (getSuffix a) b)
  144.                 (format t "~%")
  145.             )
  146.         )
  147.     )
  148.     (parse-error (c)
  149.         (format t "예외상황: ~A" c)
  150.         (format t "이 발생였음. 다시 하시오,~%~%")
  151.     )
  152. )




실행> clisp makeDivisionTable.lsp 500210 61

나눗셈 500210 ÷ 61 의 결과: 몫: 8200, 나머지: 10

          8200
      ________
   61 ) 500210
        488
        ------
         122
         122
        ------
            10

나머지: 10
500210 = 61 x 8200 + 10
500210은 61의 배수(mupltiple)가 아니다.




Posted by Scripter
,