2008년 06월 23일
부탁받은 Scheme 문제 003
'부탁받은 Scheme 문제 002'를 이어갑니다.
Problem 2. Write a procedure (create-list . args)
that accepts any number of values and
returns a message-passing object that handles the following operations:
'all
Returns the full list
'first
Returns the first item in the list.
'rest
Returns the rest of the items in the list.
'last
Returns the last item in the list.
'length
Returns the length of list
'list-ref
Returns a procedure that accepts an index
and returns the item at that index.
'map
Returns a procedure that accepts a procedure
and returns the result of mapping the list to it.
'filter
Returns a procedure that accepts a predicate
and returns the result of filtering the list with it.
'for-each
Returns a procedure that accepts a procedure,
evaluates the procedure with each value in the list, and returns 'done.
'member?
Returns a procedure that accepts a value
and returns #t if the value is in the list and #f otherwise.
Note: Remember, Scheme will automatically form the list, args,
out of all arguments to create-list.
Hint: You do not have to write any lengthy code for the individual operations
if you utilize your code from past homeworks and labs,
as well as Scheme's built-in procedures.
The purpose of this problem is to get practice
in setting up these types of procedures.
code:
;; More Message-Passing
;; ----------------------
(define (create-list . args)
"Code Goes Here"
)
;; Test Code
;; -----------
(define myList (create-list 5 9 2 4 1 1 0 2 -4 2 6))
(myList 'all)
(myList 'first)
(myList 'rest)
(myList 'last)
(myList 'length)
((myList 'list-ref) 0)
((myList 'list-ref) 4)
((myList 'list-ref) (-1+ (myList 'length)))
((myList 'map) square)
((myList 'filter) positive?)
((myList 'filter) odd?)
((myList 'member?) 5)
((myList 'member?) 1)
((myList 'member?) -4)
((myList 'member?) 6)
((myList 'member?) 8)
;; Additional Step 3 Test:
;(newline)
;(display "For-Each Output:") (newline)
;(((create-list 5 9 2 4 1 1 0 2 -4 2 6) 'for-each) (lambda (x) (display "> ") (display x) (newline)))
이번에는 create-list라는 프로시저를 만드는 문제입니다.
arguments가 고정되어 있는 것이 아닙니다.
그렇다면 args는 list로 날아오죠.^^
Hint로 utilize를 할 수 있다고 합니다만, 여기에 대해 잘 모르는터라 무식하게 했습니다.
즉, Scheme에서 제공하는 것을 최대한 사용하지 않았습니다.
방식은 앞에 풀어본 문제와 비슷합니다.
다만 args가 list이니 이것만 조심하면 됩니다.^^

잘 되는군요.^^
덕분에 cons와 list, recursive와 iteration에 대해서 기억을 되살릴 수 있었습니다.
역시 시간 있을 때 문제를 풀어야하는 듯싶습니다.^^;;
; 참과 거짓 그리고 제곱 프로시저
(define TRUE (= 0 0))
(define FALSE (= 0 1))
(define (square x) (* x x))
; answer
(define (create-list . args)
; 리스트의 마지막 원소 찾는 프로시저
(define (find_last_item list)
(if (null? (cdr list))
(car list)
(find_last_item (cdr list))))
; 리스트 길이 알아내는 프로시저
(define (check_length_list list sum)
(if (null? list)
sum
(check_length_list (cdr list) (+ sum 1))))
; 리스트의 인덱스에 맞는 아이템 반환하는 프로시저
; list 제일 처음 아이템의 index는 1
(define (pop_list list index)
(if (<= index 1)
(car list)
(pop_list (cdr list) (- index 1))))
; list에 map 하는 프로시저
; Scheme에서 제공하는 프로시저가 있는 듯싶으나 정확히 기억이 나지 않음.
; 따라서 예전 기억을 되살려서 만들어 보았습니다.
(define (map_list p list)
(if (null? list)
null
(cons (p (car list)) (map_list p (cdr list)))))
; for each 프로시저
; 각 아이템에 프로시저를 적용시키기만 한다.
; 다 끝나면 'done을 리턴한다.
(define (for_each p list)
(cond ((eq? list null) 'done)
(else (p (car list)) (for_each p (cdr list)))))
; member? 프로시저
; 각 아이템이 value와 같은지 확인한다.
(define (ismember list value)
(if (null? list)
FALSE
(if (eq? value (car list))
TRUE
(ismember (cdr list) value))))
; body
(lambda (op_type)
(cond ((eq? op_type 'all) args)
((eq? op_type 'first) (car args))
((eq? op_type 'rest) (cdr args))
((eq? op_type 'last) (find_last_item args))
((eq? op_type 'length) (check_length_list args 0))
((eq? op_type 'list-ref) (lambda (index) (pop_list args index)))
((eq? op_type 'map) (lambda (p) (map_list p args)))
((eq? op_type 'filter) (lambda (predicate_p) (map_list predicate_p args)))
((eq? op_type 'for-each) (lambda (p) (for_each p args)))
((eq? op_type 'member?) (lambda (value) (ismember args value)))
))
)
;; Test Code
;; -----------
(define myList (create-list 5 9 2 4 1 1 0 2 -4 2 6))
(myList 'all)
(myList 'first)
(myList 'rest)
(myList 'last)
(myList 'length)
((myList 'list-ref) 0)
((myList 'list-ref) 4)
((myList 'list-ref) (- 1 (myList 'length)))
((myList 'map) square)
((myList 'filter) positive?)
((myList 'filter) odd?)
((myList 'member?) 5)
((myList 'member?) 1)
((myList 'member?) -4)
((myList 'member?) 6)
((myList 'member?) 8)
;; Additional Step 3 Test:
(newline)
(display "For-Each Output:") (newline)
(((create-list 5 9 2 4 1 1 0 2 -4 2 6) 'for-each) (lambda (x) (display "> ") (display x) (newline)))
# by | 2008/06/23 19:58 | 트랙백 | 덧글(0)









☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]