From bff31e022f18e4e55969fe09c8b7e2b0270b1d07 Mon Sep 17 00:00:00 2001 From: "github@esslinger.dev" Date: Sat, 8 Oct 2022 11:46:55 +0200 Subject: [PATCH 1/3] feat(maths): add `IsLeapYear` --- Maths/IsLeapYear.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Maths/IsLeapYear.ts diff --git a/Maths/IsLeapYear.ts b/Maths/IsLeapYear.ts new file mode 100644 index 00000000..28e7688a --- /dev/null +++ b/Maths/IsLeapYear.ts @@ -0,0 +1,30 @@ +/** + * @function IsLeapYear + * @description Checks if a year is a leap year (Gregorian calendar). + * A year is a leap year if it is divisible by 4 but not by 400 or if it is divisible by 400. + * @param {number} year - A year, natural number > 0. + * @return {boolean} - True if given year is a leap year. + * @see https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar + * @example IsLeapYear(2000) = true + * @example IsLeapYear(2001) = false + */ + +export const IsLeapYear = (year: number): boolean => { + if (year <= 0 || !Number.isInteger(year)) { + throw new Error("year must be a natural number > 0"); + } + + if (year % 4 > 0) { + return false; + } + + if (year % 100 > 0) { + return true; + } + + if (year % 400 > 0) { + return false; + } + + return true; +}; From 2ced177c36ae88fedc09b972f689151b8f17b09a Mon Sep 17 00:00:00 2001 From: "github@esslinger.dev" Date: Sat, 8 Oct 2022 11:47:03 +0200 Subject: [PATCH 2/3] test(maths): add `IsLeapYear` tests --- Maths/test/IsLeapYear.test.ts | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Maths/test/IsLeapYear.test.ts diff --git a/Maths/test/IsLeapYear.test.ts b/Maths/test/IsLeapYear.test.ts new file mode 100644 index 00000000..79acb8bd --- /dev/null +++ b/Maths/test/IsLeapYear.test.ts @@ -0,0 +1,66 @@ +import { IsLeapYear } from "../IsLeapYear"; + +describe("IsLeapYear", () => { + test.each([4, 8, 12, 2004])( + "a year is a leap year it is divisible by 4 but not by 400 like %i", + (year) => { + expect(year % 4 === 0).toBe(true); + expect(year % 400 === 0).toBe(false); + expect(IsLeapYear(year)).toBe(true); + }, + ); + + test.each([400, 800, 1200, 1600, 2000, 2400, 40000])( + "a year is a leap year it is divisible by 400 like %i", + (year) => { + expect(year % 400 === 0).toBe(true); + expect(IsLeapYear(year)).toBe(true); + }, + ); + + test.each([1, 313, 1997, 2001, 2021, 13337])( + "a year is not a leap year if it is not divisible by 4 like %i", + (year) => { + expect(year % 4 === 0).toBe(false); + expect(IsLeapYear(year)).toBe(false); + }, + ); + + test.each([100, 200, 300, 700, 2100])( + "a year is not a leap year if it is divisible by 100 but not by 400 like %i", + (year) => { + expect(year % 100 === 0).toBe(true); + expect(year % 400 === 0).toBe(false); + expect(IsLeapYear(year)).toBe(false); + }, + ); + + test.each([1, 2022, 3000000])( + "a year is supported if it is a natural number > 0 like %i", + (year) => { + expect(year > 0).toBe(true); + expect(Number.isInteger(year)).toBe(true); + expect(() => IsLeapYear(year)).not.toThrow(); + }, + ); + + test.each([-1, -10, -Infinity])( + "a year is not supported if it is negative like %i", + (year) => { + expect(year < 0).toBe(true); + expect(() => IsLeapYear(year)).toThrow("year must be a natural number > 0"); + }, + ); + + test.each([0.1, 1.2, 4.2])( + "a year is not supported if it is not an integer %d", + (year) => { + expect(Number.isInteger(year)).toBe(false); + expect(() => IsLeapYear(year)).toThrow("year must be a natural number > 0"); + }, + ); + + test("a year is not supported if it is 0", () => { + expect(() => IsLeapYear(0)).toThrow("year must be a natural number > 0"); + }) +}); From f0d56deb1dafb4007e7ce30fcb517d41461b49f4 Mon Sep 17 00:00:00 2001 From: "github@esslinger.dev" Date: Sat, 8 Oct 2022 11:57:58 +0200 Subject: [PATCH 3/3] refactor(maths): compress if statements in `IsLeapYear` --- Maths/IsLeapYear.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Maths/IsLeapYear.ts b/Maths/IsLeapYear.ts index 28e7688a..0d607bb5 100644 --- a/Maths/IsLeapYear.ts +++ b/Maths/IsLeapYear.ts @@ -14,17 +14,5 @@ export const IsLeapYear = (year: number): boolean => { throw new Error("year must be a natural number > 0"); } - if (year % 4 > 0) { - return false; - } - - if (year % 100 > 0) { - return true; - } - - if (year % 400 > 0) { - return false; - } - - return true; + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); };