|
| 1 | +;;;; Gauss's Easter algorithm implementation |
| 2 | + |
| 3 | +(defun computus (year &optional (servois nil)) |
| 4 | + "Calculates the day of Easter for a given year and optionally its Servois number" |
| 5 | + (let* |
| 6 | + ((a (mod year 19)) ; year's position on the 19 year metonic cycle |
| 7 | + (k (floor year 100)) ; century index |
| 8 | + (p (floor (+ 13 (* 8 k)) 25)) ; shift of metonic cycle, add a day offset every 300 years |
| 9 | + (q (floor k 4)) ; correction for non-observed leap days |
| 10 | + (m (mod (+ 15 (- p) k (- q)) 30)) ; correction to starting point of calculation each century |
| 11 | + (d (mod (+ (* 19 a) m) 30)) ; number of days from March 21st until the full moon |
| 12 | + (n (mod (+ 4 k (- q)) 7)) ; century-based offset in weekly calculation |
| 13 | + (b (mod year 4)) ; correction for leap days |
| 14 | + (c (mod year 7)) ; also a correction for leap days |
| 15 | + ;; days from d to next Sunday |
| 16 | + (e (mod (+ (* 2 b) (* 4 c) (* 6 d) n) 7))) |
| 17 | + ;; historical corrections for April 26 and 25 |
| 18 | + (when (or (and (eql d 29) (eql e 6)) (and (eql d 28) (eql e 6) (> a 10))) |
| 19 | + (setf e -1)) |
| 20 | + (values |
| 21 | + ;; determination of the correct month for Easter |
| 22 | + (if (> (+ 22 d e) 31) |
| 23 | + (format nil "April ~a" (+ d e -9)) |
| 24 | + (format nil "March ~a" (+ 22 d e))) |
| 25 | + ;; optionally return a value for the Servois' table |
| 26 | + (if servois (mod (+ 21 d) 31))))) |
| 27 | + |
| 28 | +(format t "~{~a~%~}" |
| 29 | + '("The following are the dates of the Paschal full moon (using Servois" |
| 30 | + "notation) and the date of Easter for 2020-2030 AD:~%" |
| 31 | + "Year Servois number Easter")) |
| 32 | +(loop for year from 2020 to 2030 do |
| 33 | + (multiple-value-bind (easter servois) (computus year t) |
| 34 | + (format t "~8a~18a~a~%" year servois easter))) |
0 commit comments