P1-WS04-MusterLoesung10.txt

Aus Fachschaft_Informatik
Zur Navigation springen Zur Suche springen
Die druckbare Version wird nicht mehr unterstützt und kann Darstellungsfehler aufweisen. Bitte aktualisiere deine Browser-Lesezeichen und verwende stattdessen die Standard-Druckfunktion des Browsers.
	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