# 동료채점 평가 방법 + 예시 ## 방법 * 코멘트는 크게 1) 정확성과 2) 가독성으로 나누어져 있습니다. 각 항목마다 점수를 먼저 적고, 왜 그런 점수를 주었는지에 대한 설명을 적습니다. + 각 설명은 이와 같이 + 항목으로 적어주세요. * 코드가 틀렸다고 해서 옳은 답을 뭉터기로 적어주지 말고, 틀린 코드가 왜 틀렸는지, 그리고 어디를 고치면 옳게 될지 알려줍니다. * 코드 줄을 지칭하여 코멘트가 필요한 경우, 다음과 같이 [함수이름:줄번호.코멘트] 형식으로 나타내주세요. 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)) 다음은 평가 예시입니다. * 정확성: 1/3 + 코드에 Euclidean 호제법의 아이디어가 녹아있음. + 하지만 끝나지 않는 케이스 존재함. 예를 들어 (gcd 3 0)은 (gcd 3 0) 자기 자신을 부름. + gcd:2. (- x y)를 계산하기 전에 x가 y보다 큰지 확인해야 함. 만일 그렇지 않다면 (gcd y x)를 부르도록 고쳐야함. + 또한 y가 0이라면 x를 답으로 반환해야 함. * 가독성: 2/2 + 코드가 무엇을 하는지, 그리고 어떤 원리에 입각해 작성되었는지 모두 잘 드러나 있음. ### 문제 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 ) ) 다음은 평가 예시입니다. * 정확성: 3/3 + 제공된 모든 테스트 케이스에서 올바르게 동작함. * 가독성: 2/2 + 주어진 문제(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))))))))) 다음은 평가 예시입니다. * 정확성: 2/3 + 인자가 0인 경우를 제외하고는 모두 올바른 결과를 출력함. 인자가 0인 경우 (void)를 실행하여 아무 출력도 하지 않음. + yanghui:3. 빈문자열을 출력하도록 (void)를 빈 문자열 ""로 수정해야 함. * 가독성: 2/2 + 각 보조함수가 하는 일을 잘 설명하고 있음. + 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. 다음은 평가 예시입니다. * 정확성: 2/3 + 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. 입력 타입에 맞게 수정해야 함. * 가독성: 2/2 + 코멘트로 각 함수가 하는 일을 잘 설명하고 있음. ### 문제 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)))) 다음은 평가 예시입니다. * 정확성: 3/3 + 제공된 모든 테스트 케이스에서 올바르게 동작함. * 가독성: 1/2 + 큰 문제(crazy2add)를 작은 문제들(add, sum, char)로 나눠서 풀었다는 아이디어가 명확히 드러나 있음. + 함수 sum과 add는 설명이 없으면 무엇을 하는 함수인지 알아보기가 힘듦. 각 함수가 어떤 목적을 가지고 있는지, 그리고 왜 동작하는지에 관한 설명이 있었으면 좋았을 듯.