Skip to content

Commit 78171e0

Browse files
authored
[Haskell] Computus (#679)
1 parent b4b5071 commit 78171e0

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
data Mode = Servois | Easter
2+
3+
computus :: Mode -> Int -> String
4+
computus mode year =
5+
case mode of
6+
Servois ->
7+
-- Value for Servois' table
8+
show $ (21 + d) `mod` 31
9+
Easter ->
10+
-- Determination of the correct month for Easter
11+
if 22 + d + f > 31
12+
then "April " ++ show (d + f - 9)
13+
else "March " ++ show (22 + d + f)
14+
where
15+
a, b, c, d, e, f, k, m, n, p, q :: Int
16+
-- Year's position on the 19 year metonic cycle
17+
a = year `mod` 19
18+
-- Century index
19+
k = year `div` 100
20+
-- Shift of metonic cycle, add a day offset every 300 years
21+
p = (13 + 8 * k) `div` 25
22+
-- Correction for non-observed leap days
23+
q = k `div` 4
24+
-- Correction to starting point of calculation each century
25+
m = (15 - p + k - q) `mod` 30
26+
-- Number of days from March 21st until the full moon
27+
d = (19 * a + m) `mod` 30
28+
-- Finding the next Sunday
29+
-- Century-based offset in weekly calculation
30+
n = (4 + k - q) `mod` 7
31+
-- Correction for leap days
32+
b = year `mod` 4
33+
c = year `mod` 7
34+
-- Days from d to next Sunday
35+
e = (2 * b + 4 * c + 6 * d + n) `mod` 7
36+
-- Historical corrections for April 26 and 25
37+
f =
38+
if (d == 29 && e == 6) || (d == 28 && e == 6 && a > 10)
39+
then -1
40+
else e
41+
42+
-- Here, we will output the date of the Paschal full moon
43+
-- (using Servois notation), and Easter for 2020-2030
44+
main :: IO ()
45+
main = do
46+
let years :: [Int]
47+
years = [2020 .. 2030]
48+
servoisNumbers, easterDates :: [String]
49+
servoisNumbers = map (computus Servois) years
50+
easterDates = map (computus Easter) years
51+
putStrLn "The following are the dates of the Paschal full moon (using Servois notation) and the date of Easter for 2020-2030 AD:"
52+
putStrLn "Year\tServois number\tEaster"
53+
let conc :: Int -> String -> String -> String
54+
conc y s e = show y ++ "\t" ++ s ++ "\t\t" ++ e
55+
mapM_ putStrLn $ zipWith3 conc years servoisNumbers easterDates

contents/computus/computus.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ For now, we have the code outputting a tuple of $$d$$ and $$e$$, so users can us
281281
{% method %}
282282
{% sample lang="jl" %}
283283
[import, lang:"julia"](code/julia/gauss_easter.jl)
284+
{% sample lang="hs" %}
285+
[import, lang:"haskell"](code/haskell/gauss_easter.hs)
284286
{% sample lang="py" %}
285287
[import, lang:"python"](code/python/gauss_easter.py)
286288
{% sample lang="crystal" %}

0 commit comments

Comments
 (0)