엄청 지저분해졌지만 그런대로. 답 나옴..
2진수의 곱을 이쁘게 출력하는 함수..

2진수의 곱을 이쁘게 출력하는 함수..
;; 이쁘게 찍기
(defun pretty-print-mul (a b)
(let ((ans (binary-mul a b))
(lst (reverse (binary-bit-calculate a b))))
(let ((digits (length ans)))
(format t "~A~%" (fill-spacer a digits))
(format t "~A~%" (fill-spacer b digits))
(format t "~A~%" (fill-spacer (dashes (max (length a) (length b))) digits))
(dolist (ele lst)
(format t "~A~%" (fill-spacer ele digits)))
(format t "~A~%" (fill-spacer (dashes (length ans)) digits))
(format t "~A~%" (fill-spacer ans digits)))))
(defun dashes (n)
(cond ((= n 0) "")
(t (string-concat "-"
(dashes (- n 1))))))
(defun binary-mul (a b)
(trim-left-zero (sumup (binary-bit-calculate a b))))
;; 2진수 문자열을 풀어서 각 자리수별로 연산 결과를 만들기...
;; 자리수가 증가할 수록 뒷부분에 문자열도 따라서 증가해야한다.
(defun binary-bit-calculate (a b)
(cond ((= (length b) 0) '())
(t
(cons
(string-concat (binary-and a (char b 0)) (spacer (- (length b) 1)))
(binary-bit-calculate a (subseq b 1 (length b)))))))
(defun sumup (lst)
(cond ((null lst) "")
(t (binary-bit-add (car lst)
(sumup (cdr lst))))))
;; 앞쪽의 0 지우기..
(defun trim-left-zero (str)
(cond ((not (char= (char str 0) #\0)) str)
(t
(trim-left-zero (subseq str 1 (length str))))))
;; 2진수 문자열의 합
(defun binary-bit-add (a b)
(let ((la (length a))
(lb (length b)))
(let ((ll (max la lb)))
(let ((ra (fill-spacer a ll))
(rb (fill-spacer b ll)))
(binary-add ra rb)))))
(defun fill-spacer (s n)
(cond ((= (length s) n) s)
(t
(string-concat (string " ")
(fill-spacer s (- n 1))))))
;; 2진수의 합 계산하기..
; 각 항의 값을 더하고 캐리가 발생하면 다음 자리로 올린다.
; Reverse 가 된 것이라고 가정
(defun rev-binary-add (a b)
(labels ((adds (a b)
(cond ((and (char= a #\1) (or (char= b #\0) (char= b #\Space))) "1")
((and (or (char= a #\0) (char= a #\Space)) (char= b #\1)) "1")
(t "0")))
(cadds (a b)
(cond ((and (char= b #\1) (char= a #\1)) "1")
(t "0")))
(binary-iter (c a b)
(cond ((= (length a) 0) c)
(t
(let ((fa (char a 0))
(fb (char b 0))
(ans (string "0"))
(carry (string "0")))
(progn
(setf ans (adds fa fb))
(setf carry (cadds fa fb))
(cond ((string= c "1")
(if (string= ans "1")
(progn
(setf ans (string "0"))
(setf carry (string "1")))
(setf ans (string "1")))))
(string-concat ans
(binary-iter carry
(subseq a 1 (length a))
(subseq b 1 (length b))))))))))
(binary-iter (string "0")
a
b)))
(defun binary-add (a b)
(reverse (rev-binary-add (reverse a)
(reverse b))))
(defun stringloop (a)
(cond ((= (length a) 0) (string ""))
(t
(stringloop
(subseq a 1 (length a))))))
;; 어떤 이진수 A와 0, 1의 곱 결과를 돌려주기.
(defun binary-and (a b)
(cond ((char= b #\0)
(zeros (length a)))
(t a)))
;; 특정 길이만큼 0로 찬 결과를 돌려주기..
(defun zeros (n)
(cond ((= n 0) (string ""))
(t
(string-concat (string "0")
(zeros (- n 1))))))
;; 특정 길이만큼 스페이스
(defun spacer (n)
(cond ((= n 0) (string ""))
(t
(string-concat (string " ")
(spacer (- n 1))))))

댓글 없음:
댓글 쓰기