CSCI 316: Lisp Assignment 3
This document includes Kong’s official Scheme solutions that were posted after the submission deadline. They have been translated to Common Lisp by an LLM.
Due Date: Tuesday, October 21
Prerequisite: Complete Lisp Assignment 2 first
Submissions after this due date will be accepted as late submissions until a late-submission deadline in December that will be announced later. See page 3 of the 1st-day announcements document for information on late-submission penalties.
Important: Students should have entered source /home/faculty/ykong/316setup at the xxxxx_yyyy316@mars:~$ prompt weeks ago. You won’t be able to submit this assignment unless you have done that!
Assignment Details:
- This assignment counts 0.6% towards your grade if the grade is computed using Rule A
- You may work with up to two other students if you wish
- Each student working with partners must write up their submission independently in their own file—no two students are to submit copies of the same file
Coding Requirements:
- Program in a functional style without using SETF
- Do not use any features of Lisp other than those introduced in lectures and/or the assigned reading
- Follow the indentation and spacing rules in the
indentation-&-spacing-rules-for-Lisp-Assignments-2-3-4-5document on Brightspace
Assigned Problems
-
Define a LISP function
MIN-2with the following properties:MIN-2takes two arguments, A and B.- If A and B are numbers such that A ≤ B, then
MIN-2returns A - If A and B are numbers such that A > B, then
MIN-2returns B - If A or B is not a number, then
MIN-2returns the symbolERROR
Examples:
(MIN-2 21.3 7/2) => 7/2 (MIN-2 17.5 29) => 17.5 (MIN-2 5 'APPLE) => ERROR (MIN-2 '(31) '(54)) => ERRORScheme Solution
(define (min-2 a b) (cond ((not (real? a)) 'error) ((not (real? b)) 'error) ((<= a b) a) (else b)))Common Lisp Solution
(defun min-2 (a b) (cond ((not (realp a)) 'error) ((not (realp b)) 'error) ((<= a b) a) (t b))) - If A and B are numbers such that A ≤ B, then
-
[Exercise 4 on p. 72 of Wilensky] Write a LISP function
SAFE-AVGthat takes 2 arguments and returns the average of those arguments if they are numbers. If one or both of the arguments is not a number, the function should returnNIL.Examples:
(SAFE-AVG 23 47.4) => 35.2 (SAFE-AVG 3 8) => 11/2 (SAFE-AVG '(23.1) 47.3) => NIL (SAFE-AVG 'ORANGE 'PLUM) => NILScheme Solution
(define (safe-avg x y) (and (number? x) (number? y) (/ (+ x y) 2)))Common Lisp Solution
(defun safe-avg (x y) (and (numberp x) (numberp y) (/ (+ x y) 2))) -
[Exercise 2 on p. 72 of Wilensky] Write a LISP predicate
ODD-GT-MILLIONthat takes one argument, and which returns T if its argument is an odd integer greater than a million, but returnsNILotherwise.Hint: Make use of the predicate
INTEGERP.Examples:
(ODD-GT-MILLION 92010231) => T (ODD-GT-MILLION 17) => NIL (ODD-GT-MILLION 92010232) => NIL (ODD-GT-MILLION 21/5) => NIL (ODD-GT-MILLION 1718671.24) => NIL (ODD-GT-MILLION '(2010231)) => NIL (ODD-GT-MILLION 'APPLE) => NILScheme Solution
(define (odd-gt-million x) (and (integer? x) (> x 1000000) (odd? x)))Common Lisp Solution
(defun odd-gt-million (x) (and (integerp x) (> x 1000000) (oddp x))) -
[Exercise 3 on p. 72 of Wilensky] Write a LISP predicate
MULTIPLE-MEMBERthat takes two arguments and behaves as follows: If the first argument is a symbol or number and the second is a list, thenMULTIPLE-MEMBERreturns a non-null value if the first argument occurs at least twice in the second argument, but returnsNILotherwise.Examples:
(MULTIPLE-MEMBER 'A '(B A B B A C A D)) => (A C A D) (MULTIPLE-MEMBER 3 '(B 3 B B C C 3 D)) => (3 D) (MULTIPLE-MEMBER 3 '(B 3 B B C D)) => NIL (MULTIPLE-MEMBER 'A '(B C D)) => NILNote: The behavior of
MULTIPLE-MEMBERis unspecified in cases where the first argument is not a symbol or number, and in cases where the second argument is not a list. Your definition may therefore return any value or produce an evaluation error in such cases.Scheme Solution
;;; The following helping function for multiple-member ;;; has the property that (safe-cdr #f) => (), so ;;; (safe-cdr (member x l)) => () if (member x l) => #f. ;;; In Common Lisp, cdr can be used instead of safe-cdr, ;;; because in Common Lisp (cdr nil) => nil and so ;;; (cdr (member x l)) => nil if (member x l) => nil. ;;; (define (safe-cdr l) (if (pair? l) (cdr l) '())) ;;; (define (multiple-member x l) (member x (safe-cdr (member x l))))Common Lisp Solution
(defun multiple-member (x l) (member x (cdr (member x l)))) -
Define a LISP function
MONTH->INTEGERwhich takes as argument a symbol that should be the name of a month, and which returns the number of the month.Examples:
(MONTH->INTEGER 'MARCH) => 3 (MONTH->INTEGER 'JUNE) => 6If the argument is not a symbol that is the name of a month, the function should return the symbol
ERROR.Examples:
(MONTH->INTEGER 'C) => ERROR (MONTH->INTEGER 7) => ERROR (MONTH->INTEGER 'QUOTE) => ERROR (MONTH->INTEGER '(MAY)) => ERRORScheme Solution
(define (month->integer m) (cond ((equal? m 'january) 1) ((equal? m 'february) 2) ((equal? m 'march) 3) ((equal? m 'april) 4) ((equal? m 'may) 5) ((equal? m 'june) 6) ((equal? m 'july) 7) ((equal? m 'august) 8) ((equal? m 'september) 9) ((equal? m 'october) 10) ((equal? m 'november) 11) ((equal? m 'december) 12) (else 'error)))Common Lisp Solution
(defun month->integer (m) (cond ((equal m 'january) 1) ((equal m 'february) 2) ((equal m 'march) 3) ((equal m 'april) 4) ((equal m 'may) 5) ((equal m 'june) 6) ((equal m 'july) 7) ((equal m 'august) 8) ((equal m 'september) 9) ((equal m 'october) 10) ((equal m 'november) 11) ((equal m 'december) 12) (t 'error))) -
Define a LISP function
SCORE->GRADEwhich takes a single argument, s, and returns a symbol according to the following scheme:Range Grade s ≥ 90 A 87 ≤ s < 90 A– 83 ≤ s < 87 B+ 80 ≤ s < 83 B 77 ≤ s < 80 B– 73 ≤ s < 77 C+ 70 ≤ s < 73 C 60 ≤ s < 70 D s < 60 F If the argument s is not a number then the function should return
NIL.Examples:
(SCORE->GRADE 86.3) => B+ (SCORE->GRADE 106) => A (SCORE->GRADE –10.1) => F (SCORE->GRADE 59.9) => F (SCORE->GRADE 83) => B+ (SCORE->GRADE 74) => C+ (SCORE->GRADE 67) => D (SCORE->GRADE 87.0) => A– (SCORE->GRADE '(86.3)) => NIL (SCORE->GRADE 'DOG) => NILScheme Solution
(define (score->grade s) (cond ((not (real? s)) 'nil) ((>= s 90) 'a) ((>= s 87) 'a-) ((>= s 83) 'b+) ((>= s 80) 'b) ((>= s 77) 'b-) ((>= s 73) 'c+) ((>= s 70) 'c) ((>= s 60) 'd) (else 'f)))Common Lisp Solution
(defun score->grade (s) (cond ((not (realp s)) nil) ((>= s 90) 'a) ((>= s 87) 'a-) ((>= s 83) 'b+) ((>= s 80) 'b) ((>= s 77) 'b-) ((>= s 73) 'c+) ((>= s 70) 'c) ((>= s 60) 'd) (t 'f)))
Problems 7–9: Without COND, IF, WHEN, UNLESS, or CASE
Solve problems 7–9 below without using COND, IF, WHEN, UNLESS or CASE.
Note: WHEN, UNLESS, and CASE have not been covered in this course, so students are not expected to have any knowledge of those three macros.
Reminder: Do not use COND, IF, WHEN, UNLESS or CASE when solving the three problems below.
-
Define a LISP function
GTwith the following properties:GTtakes two arguments. It returns T if the arguments are numbers and the first argument is greater than the second; otherwise it returnsNIL.Examples:
(GT 0 –1) => T (GT –3 –7) => T (GT 40 40) => NIL (GT 'B 'A) => NILRemember: Do not use COND, IF, WHEN, UNLESS, or CASE!
Scheme Solution
(define (gt x y) (and (real? x) (real? y) (> x y)))Common Lisp Solution
(defun gt (x y) (and (realp x) (realp y) (> x y))) -
Define a LISP function
SAME-PARITYwith the following properties:SAME-PARITYtakes two arguments. It returns T if both arguments are even integers or if both arguments are odd integers. In all other casesSAME-PARITYreturnsNIL.Examples:
(SAME-PARITY 0 –1) => NIL (SAME-PARITY –3 –9) => T (SAME-PARITY 30 90) => T (SAME-PARITY 'A 3) => NIL (SAME-PARITY 4 3.7) => NILScheme Solution
(define (same-parity x y) (and (integer? x) (integer? y) (or (and (even? x) (even? y)) (and (odd? x) (odd? y)))))Common Lisp Solution
(defun same-parity (x y) (and (integerp x) (integerp y) (or (and (evenp x) (evenp y)) (and (oddp x) (oddp y))))) -
Define a LISP function
SAFE-DIVwith the following properties:SAFE-DIVtakes two arguments. If both arguments are numbers and the second does not satisfyZEROP, then the function returns the result of dividing the first argument by the second. In all other cases it returnsNIL.Examples:
(SAFE-DIV 6 4) => 3/2 (SAFE-DIV 6.0 4) => 1.5 (SAFE-DIV 6 0) => NIL (SAFE-DIV 6 0.0) => NIL (SAFE-DIV '(6) 4) => NIL (SAFE-DIV 6 T) => NILScheme Solution
(define (safe-div x y) (and (number? x) (number? y) (not (zero? y)) (/ x y)))Common Lisp Solution
(defun safe-div (x y) (and (numberp x) (numberp y) (not (zerop y)) (/ x y)))
Submission Instructions
See submission-instructions.md for general submission guidelines that apply to all Lisp assignments.
Assignment-Specific Notes
In this document, the term list should be understood to mean proper list.
Wrongly named functions (e.g., a function for problem 5 named MNTH->INTEGER or MONTH-INTEGER instead of MONTH->INTEGER) are likely to receive no credit!
Unless you are running Clisp as a subprocess of emacs, each time you write or modify a function it is good to:
- Save the file
- Re-LOAD it into Clisp
- Immediately test the new/modified function
Questions about the problems that are emailed to me will not be answered before the submission deadline.
Note: This assignment counts 0.6% towards your grade if the grade is computed using Rule A.