P1 Übungen WS2004/2005
Musterlösung 10 (Martin Burmester)
Aufgabe 1.)
; (a)
(define (ostersonntag j)
(let*
; 1. Argument vom let*. Berechnen wir a,b,c,d,e,m,
((a (remainder j 19) )
(b (remainder j 4) )
(c (remainder j 7) )
(m (cond ((<= 1800 j 1899) 23)
((<= 1900 j 2099) 24)
((<= 2100 j 2199) 24)
(else (error "year out of range!"))))
(n (cond ((<= 1800 j 1899) 4)
((<= 1900 j 2099) 5)
((<= 2100 j 2199) 6)
(else (error "year out of range!"))))
(d (remainder (+ (* 19 a) m)
30))
(e (remainder (+ (* 2 b)
(* 4 c)
(* 6 d)
n)
7))
(april_day0 (+ d e -9))
(april_day (cond ((= april_day0 26) 19)
((and (= april_day0 25)
(= d 28)
(= e 6)
(>= a 10))
18)
(else april_day0)))
(march_day (+ 22 d e)))
; 2. Argument vom let*. Nun haben wir alles!
;
; 1. Versuch:
; (list march_day 'maerz j 'oder april_day 'april j)
; bekommen wir komisches datum, z.B. (-8 april ...) oder (54 maerz ...)
;
; 2. Versuch
; kontrolliere ob april_day und march_day gültig sind...
(if (> march_day 31) (list april_day 'April j)
(list march_day 'Maerz j))))
; (b)
;;
;; Jedem Monat ist die Anzahl der Tage im Monat und der
;; Folgemonat zugeordnet.
;;
(define maerz (cons 31 'april))
(define april (cons 30 'mai))
(define mai (cons 31 'juni))
(define juni (cons 30 'juli))
(define tage-im-monat car)
(define folgemonat cdr)
;;
;; Fuegt zu einem Datum d eine Anzahl von
;; Tagen t hinzu und gibt ein gueltiges
;; Datum zurück
;;
(define (datum+tage d t)
(define (korrigiere-datum d)
(let ((tag (car d))
(monat (eval (cadr d)))
(jahr (caddr d)))
(if (> tag (tage-im-monat monat))
(korrigiere-datum (list (- tag (tage-im-monat monat))
(folgemonat monat)
jahr))
d)))
(korrigiere-datum (cons (+ (car d) t)
(cdr d))))
(define (himmelfahrt j)
(datum+tage (ostersonntag j) 39))
; (c)
(define (pfingsten j)
(datum+tage (ostersonntag j) 49))
; Tes