Skip to content

Add Computus in Javascript and Typescript #807

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions contents/computus/code/javascript/gauss_easter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* In this code, the modulus operator is used.
* However, this operator in javascript/typescript doesn't support negative numbers.
* So, where there may be negative numbers, the function mod is used.
* This function gives the modulo of any relative number a
*/

/**
* @param {number} a
* @param {number} b
* @returns {number}
*/
function mod(a, b) {
if (a < 0) return mod(a + b, b);
else return a % b;
}

/**
* @param {number} year
* @param {boolean} [servois=false]
* @returns {string}
*/
function computus(year, servois = false) {
// Year's position in metonic cycle
const a = year % 19;

// Century index
const k = Math.floor(year / 100);

// Shift of metonic cycle, add a day offset every 300 years
const p = Math.floor((13 + 8 * k) / 25);

// Correction for non-observed leap days
const q = Math.floor(k / 4);

// Correction to starting point of calculation each century
const M = mod(15 - p + k - q, 30);

// Number of days from March 21st until the full moon
const d = (19 * a + M) % 30;

// Returning if user wants value for Servois' table
if (servois) return ((21 + d) % 31).toString();

// Finding the next Sunday
// Century-based offset in weekly calculation
const N = mod(4 + k - q, 7);

// Correction for leap days
const b = year % 4;
const c = year % 7;

// Days from d to next Sunday
let e = (2 * b + 4 * c + 6 * d + N) % 7;

// Historical corrections for April 26 and 25
if (e === 6) if (d === 29 || (d === 28 && a > 10)) e = -1;

// Determination of the correct month for Easter
if (22 + d + e > 31) return `April ${d + e - 9}`;
else return `March ${22 + d + e}`;
}

console.log(
"The following are the dates of the Paschal full moon (using Servois " +
"notation) and the date of Easter for 2020-2030 AD:"
);

const values = [];

for (let year = 2020; year <= 2030; year++) {
const servoisNumber = computus(year, true);
const easterDate = computus(year);

// Creation of an object to be displayed as a line in the output table
values[year] = {
"servois number": +servoisNumber,
easter: easterDate,
};
}

console.table(values);
80 changes: 80 additions & 0 deletions contents/computus/code/typescript/gauss_easter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* In this code, the modulus operator is used.
* However, this operator in javascript/typescript doesn't support negative numbers.
* So, where there may be negative numbers, the function mod is used.
* This function gives the modulo of any relative number a
*/

function mod(a: number, b: number): number {
if (a < 0) return mod(a + b, b);
else return a % b;
}

function computus(year: number, servois: boolean = false): string {
// Year's position in metonic cycle
const a = year % 19;

// Century index
const k = Math.floor(year / 100);

// Shift of metonic cycle, add a day offset every 300 years
const p = Math.floor((13 + 8 * k) / 25);

// Correction for non-observed leap days
const q = Math.floor(k / 4);

// Correction to starting point of calculation each century
const M = mod(15 - p + k - q, 30);

// Number of days from March 21st until the full moon
const d = (19 * a + M) % 30;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you aren't explicitly typing these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't explicitly type these variables to be clearer to read.
However, it may be better with types: if someone wants an implementation without types, they could use the JavaScript version.
I'll add types to every variable as soon as possible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, thanks!


// Returning if user wants value for Servois' table
if (servois) return ((21 + d) % 31).toString();

// Finding the next Sunday
// Century-based offset in weekly calculation
const N = mod(4 + k - q, 7);

// Correction for leap days
const b = year % 4;
const c = year % 7;

// Days from d to next Sunday
let e = (2 * b + 4 * c + 6 * d + N) % 7;

// Historical corrections for April 26 and 25
if (e === 6) if (d === 29 || (d === 28 && a > 10)) e = -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind bringing the reassignment into its own line? It's a bit buried at the end as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I can fix that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, would you mind doing that for all instances of inline if/else


// Determination of the correct month for Easter
if (22 + d + e > 31) return `April ${d + e - 9}`;
else return `March ${22 + d + e}`;
}

console.log(
"The following are the dates of the Paschal full moon (using Servois " +
"notation) and the date of Easter for 2020-2030 AD:"
);

// Type of a line in the output table
interface IOutputLine {
"servois number": number;
easter: string;
}

const values: IOutputLine[] = [];

for (let year = 2020; year <= 2030; year++) {
const servoisNumber = computus(year, true);
const easterDate = computus(year);

// Creation of an object to be displayed as a line in the output table
const line: IOutputLine = {
"servois number": +servoisNumber,
easter: easterDate,
};

values[year] = line;
}

console.table(values);
4 changes: 4 additions & 0 deletions contents/computus/computus.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ For now, we have the code outputting a tuple of $$d$$ and $$e$$, so users can us
[import, lang:"lisp"](code/clisp/gauss-easter.lisp)
{% sample lang="nim" %}
[import, lang:"nim"](code/nim/gauss_easter.nim)
{% sample lang="javascript" %}
[import, lang:"nim"](code/javascript/gauss_easter.js)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll also need to change the lang "variable" to JavaScript and TypeScript. I forgot to do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch, I missed this as well

{% sample lang="typescript" %}
[import, lang:"nim"](code/typescript/gauss_easter.ts)
{% endmethod %}


Expand Down