; CSE3401 Winter 2012- assignment 4
; Vida Movahedi
;Question 1- Cash register problem
(defun calcTotal (SaleList PriceList &optional (taxrate 0))
(let* (
; Here are 7 local variables set to their initial values:
; PriceList is read from the file if null
(PrcLst (cond ((null PriceList)
(setq instream (open "c:\\vida\\lispcode\\priceList.txt" :direction :input))
(setq PriceList (read instream))
(close instream) PriceList)
(T priceList)) )
; sepList seperates SaleList into two lists saved as TwoLists
(TwoLists (sepList SaleList))
; Then Items would be the first element in TwoLists
(Items (car TwoLists))
; And Quants would be the second element in TwoLists
(Quants (car (cdr TwoLists)))
; Given PriceList, retrieve prices of Items
(prices (retAllPrices Items PrcLst))
; Then calculate sum for each item
(Sums (mapcar 'calcSumItem Quants Prices ))
; And the total before tax
(Total (eval (cons '+ Sums)))
)
; Print the total before tax
(format T "The total before tax is ~7,2f~%" Total)
; Print tax
(format T "The total tax is ~14,2f~%" (* Total taxrate))
; Print the total after tax
(format T "The total after tax is ~8,2f~%" (* Total (+ 1 taxrate)))
)
)
; retrieve the price of one item from PriceList
(defun retrieveby (item PriceList)
(do (
(tlst PriceList (cddr tlst)))
((null tlst) nil)
(if (equal (car tlst) item) (return (cadr tlst)))
))
; retrieve prices of a list of items from PriceList
(defun retAllPrices(Items PriceList)
(mapcar
(lambda(x) (retrieveby x PriceList))
Items))
; Given number (quantity) and price, calculate sum as number * price
(defun calcSumItem (number price)
(* number price)
)
; Seperate SaleList into two lists of Items and Quants (quantities)
; return value is a list of the above two lists
(defun sepList(lst)
(do (
(tlst lst (cdr (cdr tlst)))
(Items nil (cons (car tlst) Items))
(Quants nil (cons (cadr tlst) Quants))
)
((null tlst) (list Items Quants))
)
)
;====================================================================================
; Question 2- Guess the pattern
(defun guess10()
(let* (
; get the list from user
(lst ((lambda () (princ "A list of four numbers please: ") (read))))
; find the linear pattern function
(F (apply 'guessF lst))
)
; show 10 values in this pattern
(format T "~%Here are 10 values in this pattern:~%")
(prnN F (car lst) (cadr lst) 10)
))
; find the linear pattern function given 4 numbers
(defun guessf (a b c d)
(let* ( (beta (/ (- (* b c) (* a d)) (- (* b b) (* a c)) ))
(alpha (/ (- d (* beta c)) b))
)
(format T "~%The pattern function is:~%")
(prin1 (list 'lambda '(x1 x2) (cons '+ (append (list (cons '* (list alpha 'x1))) (list (cons '* (list beta 'x2)))) )))
))
; find next value given the pattern function and the previous two values
(defun nextVal (F a1 a2)
(eval (list F a1 a2))
)
; return n values given a pair and a pattern function
(defun prnN(F A1 A2 N)
(do* ( (m (- n 2) (1- m)) ; two of the n values are already known
(x (list A1 A2) (append x (list c)) ) ; initialize x with the two known values, update with adding c to list
(a A1 b) ; a: first number in a sequence of 3 numbers (a b c)
(b A2 c)
(c (nextVal F a b) (nextVal F a b) )
)
( (zerop m) x)
))
;====================================================================================
; Question 3- Write a function that deletes all odd numbers in a given list
; assume the list contains natural numbers- no checking required
; (a) using recursion
; (b) using iteration
; Using recursion
(defun DelOddRec(lst)
(cond ((null lst) lst) ; stopping condition
((oddp (car lst)) ; if head of list is an odd number,
;ignore this element and call recursively for tail
(DelOddRec (cdr lst)))
(T ; otherwise keep this element in front of the list
; returned from recursive call for the tail
(cons (car lst) (DelOddRec (cdr lst))))
)
)
; using iteration
(defun DelOddIter(lst)
(do (
(tlst lst (cdr tlst)) ; tlst, initialized by the given list and cdr'ing in each iteration
(result nil ; result, initialized by nil,
(if (oddp (car tlst)) ; if head of tlst is odd
; dont change result
result
; otherwise add the element at the end of result
(append result (list (car tlst))) ))
)
((null tlst) result)
)
)
;====================================================================================
; Question 4- write a function that calculates the dot product of two vectors
; assume the vectors are supplied as lists- no checking necessary
(defun dotproduct (V1 V2)
(apply '+ (mapcar '* V1 V2))
)
;====================================================================================
; Question 5- write a function that counts the number of words in a text file
; assume a simple case such as the provided example file.
; we count a sequence of characters (letters, numbers, signs, etc) as a word if seperated
; from adjacent seqiuences by spaces or line feeds (no need to check if they are actually words or not)
(defun countWords(filename)
(let (
; open file
(instream (open filename :direction :input))
)
(do (
; read one symbol (or word in this simple case) from file, 'eof if end of file
(next nil (read instream nil 'eof))
; increment count
(count 0 (1+ count))
)
; exit condition: if end of file
((equal next 'eof)
; then close the file, and return (count-1)- since added an extra 1 in last iteration
(close instream) (- count 1))
)
)
)