Skip to content

Commit d52db37

Browse files
committed
Add Computus in Javascript and Typescript
1 parent 442a170 commit d52db37

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* In this code, the modulus operator is used.
3+
* However, this operator in javascript/typescript doesn't support negative numbers.
4+
* So, where there may be negative numbers, the function mod is used.
5+
* This function gives the modulo of any relative number a
6+
*/
7+
8+
/**
9+
* @param {number} a
10+
* @param {number} b
11+
* @returns {number}
12+
*/
13+
function mod(a, b) {
14+
if (a < 0) return mod(a + b, b);
15+
else return a % b;
16+
}
17+
18+
/**
19+
* @param {number} year
20+
* @param {boolean} [servois=false]
21+
* @returns {string}
22+
*/
23+
function computus(year, servois = false) {
24+
// Year's position in metonic cycle
25+
const a = year % 19;
26+
27+
// Century index
28+
const k = Math.floor(year / 100);
29+
30+
// Shift of metonic cycle, add a day offset every 300 years
31+
const p = Math.floor((13 + 8 * k) / 25);
32+
33+
// Correction for non-observed leap days
34+
const q = Math.floor(k / 4);
35+
36+
// Correction to starting point of calculation each century
37+
const M = mod(15 - p + k - q, 30);
38+
39+
// Number of days from March 21st until the full moon
40+
const d = (19 * a + M) % 30;
41+
42+
// Returning if user wants value for Servois' table
43+
if (servois) return ((21 + d) % 31).toString();
44+
45+
// Finding the next Sunday
46+
// Century-based offset in weekly calculation
47+
const N = mod(4 + k - q, 7);
48+
49+
// Correction for leap days
50+
const b = year % 4;
51+
const c = year % 7;
52+
53+
// Days from d to next Sunday
54+
let e = (2 * b + 4 * c + 6 * d + N) % 7;
55+
56+
// Historical corrections for April 26 and 25
57+
if (e === 6) if (d === 29 || (d === 28 && a > 10)) e = -1;
58+
59+
// Determination of the correct month for Easter
60+
if (22 + d + e > 31) return `April ${d + e - 9}`;
61+
else return `March ${22 + d + e}`;
62+
}
63+
64+
console.log(
65+
"The following are the dates of the Paschal full moon (using Servois " +
66+
"notation) and the date of Easter for 2020-2030 AD:"
67+
);
68+
69+
const values = [];
70+
71+
for (let year = 2020; year <= 2030; year++) {
72+
const servoisNumber = computus(year, true);
73+
const easterDate = computus(year);
74+
75+
// Creation of an object to be displayed as a line in the output table
76+
values[year] = {
77+
"servois number": +servoisNumber,
78+
easter: easterDate,
79+
};
80+
}
81+
82+
console.table(values);
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* In this code, the modulus operator is used.
3+
* However, this operator in javascript/typescript doesn't support negative numbers.
4+
* So, where there may be negative numbers, the function mod is used.
5+
* This function gives the modulo of any relative number a
6+
*/
7+
8+
function mod(a: number, b: number): number {
9+
if (a < 0) return mod(a + b, b);
10+
else return a % b;
11+
}
12+
13+
function computus(year: number, servois: boolean = false): string {
14+
// Year's position in metonic cycle
15+
const a = year % 19;
16+
17+
// Century index
18+
const k = Math.floor(year / 100);
19+
20+
// Shift of metonic cycle, add a day offset every 300 years
21+
const p = Math.floor((13 + 8 * k) / 25);
22+
23+
// Correction for non-observed leap days
24+
const q = Math.floor(k / 4);
25+
26+
// Correction to starting point of calculation each century
27+
const M = mod(15 - p + k - q, 30);
28+
29+
// Number of days from March 21st until the full moon
30+
const d = (19 * a + M) % 30;
31+
32+
// Returning if user wants value for Servois' table
33+
if (servois) return ((21 + d) % 31).toString();
34+
35+
// Finding the next Sunday
36+
// Century-based offset in weekly calculation
37+
const N = mod(4 + k - q, 7);
38+
39+
// Correction for leap days
40+
const b = year % 4;
41+
const c = year % 7;
42+
43+
// Days from d to next Sunday
44+
let e = (2 * b + 4 * c + 6 * d + N) % 7;
45+
46+
// Historical corrections for April 26 and 25
47+
if (e === 6) if (d === 29 || (d === 28 && a > 10)) e = -1;
48+
49+
// Determination of the correct month for Easter
50+
if (22 + d + e > 31) return `April ${d + e - 9}`;
51+
else return `March ${22 + d + e}`;
52+
}
53+
54+
console.log(
55+
"The following are the dates of the Paschal full moon (using Servois " +
56+
"notation) and the date of Easter for 2020-2030 AD:"
57+
);
58+
59+
// Type of a line in the output table
60+
interface IOutputLine {
61+
"servois number": number;
62+
easter: string;
63+
}
64+
65+
const values: IOutputLine[] = [];
66+
67+
for (let year = 2020; year <= 2030; year++) {
68+
const servoisNumber = computus(year, true);
69+
const easterDate = computus(year);
70+
71+
// Creation of an object to be displayed as a line in the output table
72+
const line: IOutputLine = {
73+
"servois number": +servoisNumber,
74+
easter: easterDate,
75+
};
76+
77+
values[year] = line;
78+
}
79+
80+
console.table(values);

contents/computus/computus.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ For now, we have the code outputting a tuple of $$d$$ and $$e$$, so users can us
320320
[import, lang:"lisp"](code/clisp/gauss-easter.lisp)
321321
{% sample lang="nim" %}
322322
[import, lang:"nim"](code/nim/gauss_easter.nim)
323+
{% sample lang="javascript" %}
324+
[import, lang:"nim"](code/javascript/gauss_easter.js)
325+
{% sample lang="typescript" %}
326+
[import, lang:"nim"](code/typescript/gauss_easter.ts)
323327
{% endmethod %}
324328

325329

0 commit comments

Comments
 (0)