# 동료도움 방법 + 예시

## 방법

* 동료의 답안에서 틀린부분을 찾아 코멘트를 적어줍니다.

  + 각 설명은 이와 같이 + 항목으로 적어주세요.

* 코드가 틀렸다고 해서 옳은 답을 뭉터기로 적어주지 말고, 틀린 코드가 왜
  틀렸는지, 그리고 어디를 고치면 옳게 될지 알려줍니다.

* 코드 줄을 지칭하여 코멘트가 필요한 경우, 다음과 같이
  [함수이름:줄번호.코멘트] 형식으로 나타내주세요.

  foo:n. foo함수의 n번째 줄에 대한 코멘트
  foo:n-m. foo함수의 n번째에서 m번째 줄까지의 코멘트
  foo:-n. foo함수의 뒤에서 n번째 줄에 대한 코멘트
  foo:-n-m. foo함수의 뒤에서 n번째 줄에서 뒤에서 m번째 줄까지의 코멘트

  예를 들어,

    (define (abs x)
      (if (< 0 x)
          y
          (- 0 x)))

  와 같은 코드의 경우 y에 대한 코멘트를 하고 싶을 때, 

    abs:3. y에 대한 코멘트

  와 같이 하면 됩니다.

## 예시

### 문제 1

    ; gcd: greatest common divisor 
    ; 두 수 lhs, rhs의 gcd는 (lhs-rhs), rhs의 gcd와 같다. 
    ; 참고: Euclidean division 
    (define (gcd x y) 
      (gcd (- x y) y))

다음은 도움 예시입니다.

+ 코드에 Euclidean 호제법의 아이디어가 녹아있음.
+ 하지만 끝나지 않는 케이스 존재함. 
  예를 들어 (gcd 3 0)은 (gcd 3 0) 자기 자신을 부름.

+ gcd:2. (- x y)를 계산하기 전에 x가 y보다 큰지 확인해야 함.
         만일 그렇지 않다면 (gcd y x)를 부르도록 고쳐야함.
+ 또한 y가 0이라면 x를 답으로 반환해야 함. 

+ 코드가 무엇을 하는지, 그리고 어떤 원리에 입각해 작성되었는지 모두 잘
  드러나 있음.


### 문제 2

    (define (t2 n)
      (define (absolute x) ; function to calculate absolute value of input
        (if (equal? 0 x)
            0
            (if (< 0 x) x (- 0 x))))
      
      (define (s n) ; define number depend on n
        (if (> n 0)
            (string-append (s (- n 1)) "1") ; if n is bigger than 0, append n number of 1
            (string-append "0") ; if n is smaller than 0, append 0 to string(start of string)
        )
      ) 
      
      (if (or (equal? n 0) (equal? (absolute n) 1))
        (if (equal? n 0) "0" "001") ; if n is 0 or 1, make string manually
        (string-append (t2 (- (absolute n) 1)) (s (absolute n))) ; append strings start from 001 if n is bigger than 0
      )
    )

다음은 도움 예시입니다.

+ 제공된 모든 테스트 케이스에서 올바르게 동작함.

+ 주어진 문제(t2)를 해결하기 위해 작은 문제들(절대값 absolute와 숫자
  하나에 대한 문자열을 만드는 s)을 이용했다는 아이디어가 명확히 드러나
  있음.

+ 각 함수에도 적절한 주석이 달려 있어 무슨 일을 하는 함수인지 쉽게 알
  수 있음.

+ 그러나 함수 s에 대한 주석이 조금 부족.  예제가 있었다면 더 좋았을
  것.


### 문제 3

    ;(lst n m) defines a number of nth row and mth column in pascal triangle
    (define (lst n m)
        (if (= m 1) 1
            (if (= n m) 1
                (+ (lst (- n 1) (- m 1)) (lst (- n 1) m)))))
    ;(row x) prints a number from xth row
    (define (row x)
        (let rec ((k 2) (row (string #\1)))
          (if (= x 1) row
          (if (= x k) (string-append (string #\1) row)
              (rec (+ k 1) (string-append (number->string (lst x k)) row))))))
    (define (yanghui n)
        (if (< n 0) (yanghui (* n -1))
            (if (= n 0) (void)
                (let rec ((f 2) (yanghui (string #\1)))
                  (if (= n 1) yanghui
                  (if (= n (- f 1)) yanghui
                      (rec (+ f 1) (string-append yanghui (row f)))))))))

다음은 도움 예시입니다.

+ 인자가 0인 경우를 제외하고는 모두 올바른 결과를 출력함.  인자가 0인
  경우 (void)를 실행하여 아무 출력도 하지 않음.

+ yanghui:3. 빈문자열을 출력하도록 (void)를 빈 문자열 ""로 수정해야
  함.

+ 각 보조함수가 하는 일을 잘 설명하고 있음.
  
+ if문을 중첩해서 사용하기 보다는 cond명령을 사용하는 것이 더 깔끔함.
  yanghui:2-7. (cond ((< n 0) (yanghui (* n -1)))
                     ((= n 0) (void))
		       (else ...))

### 문제 4

    (define (digit n) ; this function convert the '+', '-', '0' to 1, -1 0
      (if (equal? '+ n)
          1
          (if (equal? '- n)
              -1
              (if (equal? '0 n)
                  0
                  "Wrong input"))))
    
    (define (crazy2val n) 
      (if (null? n)
          null
          (if (equal? (cdr n) '())   ; If only one element is remained in the list, (cdr n) returns '()
              (digit (car n))
              (+ (digit (car n)) (* 2 (crazy2val (cdr n)))))))
    ; by the recursive function, the binary number is converted to the decimal.

다음은 도움 예시입니다.

+ digit가 기대하는 인자의 타입이 틀림. 
  digit 함수는 '+, '-, '0을 1, -1, 0으로 변환하는 함수인데, 
  문제에서 기대하는 입력은 'p, 'n, 'z임. 
+ digit:2. '+을 'p로 바꾸어야 함.

+ crazy2val가 기대하는 인자의 타입이 틀림. 
  정의된 함수는 인자로 'z, 'n, 'p를 원소로 가지는 리스트를 기대하고 있는데, 
  문제에서 제시된 인자는 예를 들면 'z, 'n, 'p, (cons 'z 'n)와 같은 값임.

+ 예를 들어, (crazy2val 'z)를 실행하면 0을 출력해야 하지만 정의된
  함수는 다음과 같은 에러를 냄:

  cdr: contract violation
     expected: pair?
     given: 'n

+ crazy2val:2. null? 대신 pair?를 사용해야 함.
+ crazy2val:2-6. 입력 타입에 맞게 수정해야 함.

+ 코멘트로 각 함수가 하는 일을 잘 설명하고 있음.


### 문제 5

    (define (crazy2add lhs rhs)
      (add lhs rhs 0)
      )
    (define (add lhs rhs m)
      (if(and (null? lhs)(null? rhs))
            (if(equal? 0 m)
               'z
               (if(equal? 1 m)
                  'p
                  'n))
     (if(or (symbol? lhs)(null? lhs))
         (if (or (symbol? rhs)(null? rhs))
            (if (equal? 0 (+ m (+ (char lhs) (char rhs))))
                'z 
                (if (equal? 1 (+ m (+ (char  lhs) (char rhs))))
                    'p 
                    (if(equal? 2 (+ m (+ (char lhs) (char rhs))))
                       (cons 'z (add null null 1))
                       (if(equal? 3 (+ m (+ (char lhs) (char rhs))))
                          (cons 'p (add null null 1))
                          (if(equal? -1(+ m (+ (char lhs) (char rhs))))     
                             'n
                             (if(equal? -2(+ m (+ (char lhs) (char rhs))))
                                (cons 'z (add null null -1))
                                (cons 'n (add null null -1))
                                                  ))))))
            (symsum lhs rhs m))
         (if(or (symbol? rhs)(null? rhs))
            (symsum rhs lhs m)
            (sum lhs rhs m)))))
    (define (symsum lhs rhs m)
       (if (equal? 0 (+ m (+ (char lhs) (char (car rhs)))))
          (cons 'z (add null (cdr rhs) 0))
         (if (equal? 1 (+ m (+ (char  lhs) (char (car rhs)))))
             (cons 'p (add null (cdr rhs) 0))
             (if (equal? 2 (+ m (+ (char lhs) (char (car rhs)))))
                 (cons 'z (add null (cdr rhs) 1))
                 (if(equal? 3 (+ m (char lhs) (char (car rhs))))
                    (cons 'p (add null (cdr rhs) 1))
                     (if (equal? -1 (+ m (+ (char lhs) (char (car rhs)))))
                          (cons 'n (add null (cdr rhs) 0))
                          (if (equal? -2 (+ m (+ (char lhs) (char (car rhs)))))
                              (cons 'z (add null (cdr rhs) -1))
                               (cons 'n (add null (cdr rhs) -1)))))))))
    (define (sum lhs rhs m)
       (if (equal? 0 (+ m (+ (char  (car lhs)) (char  (car rhs)))))
          (cons 'z (add (cdr lhs) (cdr rhs) 0))
         (if (equal? 1 (+ m (+ (char (car lhs)) (char (car rhs)))))
             (cons 'p (add (cdr lhs) (cdr rhs) 0))
             (if (equal? 2 (+ m (+ (char (car lhs)) (char (car rhs)))))
                 (cons 'z (add (cdr lhs) (cdr rhs) 1))
                 (if(equal? 3 (+ m (+ (char (car lhs))(char (car rhs)))))
                    (cons 'p (add (cdr lhs) (cdr rhs) 1))
                    (if (equal? -1 (+ m (+ (char (car lhs)) (char (car rhs)))))
                        (cons 'n (add (cdr lhs) (cdr rhs) 0))
                        (if(equal? -2 (+ m (+ (char (car lhs))(char (car rhs)))))
                           (cons 'z (add (cdr lhs) (cdr rhs) -1))
                           (cons 'n (add (cdr lhs) (cdr rhs) -1)))))))))
    
    
    (define (char lst)
      (if(equal? lst null)
         0
         (if(equal? lst 'z)
            0
            (if(equal? lst 'p)
               1
               -1))))

다음은 도움 예시입니다.

+ 제공된 모든 테스트 케이스에서 올바르게 동작함.

+ 큰 문제(crazy2add)를 작은 문제들(add, sum, char)로 나눠서 풀었다는
  아이디어가 명확히 드러나 있음.

+ 함수 sum과 add는 설명이 없으면 무엇을 하는 함수인지 알아보기가 힘듦.
  각 함수가 어떤 목적을 가지고 있는지, 그리고 왜 동작하는지에 관한
  설명이 있었으면 좋았을 듯.