From 6bd6acdfce0ccf01614a947fc25bfcab66b4ad3d Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Thu, 27 Nov 2025 14:33:54 -0800 Subject: [PATCH] feat: catch up on fcc dailies --- .../daily/2025-11-25/main.spec.ts | 91 +++++++++++++ src/freecodecamp/daily/2025-11-25/main.ts | 32 +++++ .../daily/2025-11-26/main.spec.ts | 124 ++++++++++++++++++ src/freecodecamp/daily/2025-11-26/main.ts | 32 +++++ .../daily/2025-11-27/main.spec.ts | 50 +++++++ src/freecodecamp/daily/2025-11-27/main.ts | 51 +++++++ 6 files changed, 380 insertions(+) create mode 100644 src/freecodecamp/daily/2025-11-25/main.spec.ts create mode 100644 src/freecodecamp/daily/2025-11-25/main.ts create mode 100644 src/freecodecamp/daily/2025-11-26/main.spec.ts create mode 100644 src/freecodecamp/daily/2025-11-26/main.ts create mode 100644 src/freecodecamp/daily/2025-11-27/main.spec.ts create mode 100644 src/freecodecamp/daily/2025-11-27/main.ts diff --git a/src/freecodecamp/daily/2025-11-25/main.spec.ts b/src/freecodecamp/daily/2025-11-25/main.spec.ts new file mode 100644 index 0000000..3e846e6 --- /dev/null +++ b/src/freecodecamp/daily/2025-11-25/main.spec.ts @@ -0,0 +1,91 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { describe, it, expect } from "vitest"; +import { fizzBuzz } from "./main.js"; + +describe("fizzBuzz", () => { + it("should return the correct FizzBuzz array", () => { + expect(fizzBuzz(2)).toStrictEqual([ 1, 2 ]); + expect(fizzBuzz(4)).toStrictEqual([ 1, 2, "Fizz", 4 ]); + expect(fizzBuzz(8)). + toStrictEqual([ 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8 ]); + expect(fizzBuzz(20)).toStrictEqual([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", + 16, + 17, + "Fizz", + 19, + "Buzz", + ]); + expect(fizzBuzz(50)).toStrictEqual([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", + 16, + 17, + "Fizz", + 19, + "Buzz", + "Fizz", + 22, + 23, + "Fizz", + "Buzz", + 26, + "Fizz", + 28, + 29, + "FizzBuzz", + 31, + 32, + "Fizz", + 34, + "Buzz", + "Fizz", + 37, + 38, + "Fizz", + "Buzz", + 41, + "Fizz", + 43, + 44, + "FizzBuzz", + 46, + 47, + "Fizz", + 49, + "Buzz", + ]); + }); +}); diff --git a/src/freecodecamp/daily/2025-11-25/main.ts b/src/freecodecamp/daily/2025-11-25/main.ts new file mode 100644 index 0000000..6bdd6ca --- /dev/null +++ b/src/freecodecamp/daily/2025-11-25/main.ts @@ -0,0 +1,32 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +const getString = (number: number): string | number => { + if (number % 3 === 0 && number % 5 === 0) { + return "FizzBuzz"; + } + if (number % 3 === 0) { + return "Fizz"; + } + if (number % 5 === 0) { + return "Buzz"; + } + return number; +}; + +/** + * Given an integer (n), return an array of integers from 1 to n (inclusive), replacing numbers that are multiple of. + * @param n - The integer to generate the FizzBuzz array for. + * @returns An array of integers from 1 to n (inclusive), replacing numbers that are multiple of 3 with "Fizz", numbers that are multiple of 5 with "Buzz", and numbers that are multiple of both 3 and 5 with "FizzBuzz". + * @see https://www.freecodecamp.org/learn/daily-coding-challenge/2025-11-25 + */ +export const fizzBuzz = ( + n: number, +): Array => { + return Array.from({ length: n }, (_, index) => { + return getString(index + 1); + }); +}; diff --git a/src/freecodecamp/daily/2025-11-26/main.spec.ts b/src/freecodecamp/daily/2025-11-26/main.spec.ts new file mode 100644 index 0000000..0bca898 --- /dev/null +++ b/src/freecodecamp/daily/2025-11-26/main.spec.ts @@ -0,0 +1,124 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { describe, it, expect } from "vitest"; +import { isFizzBuzz } from "./main.js"; + +describe("isFizzBuzz", () => { + it("should return the correct result", () => { + expect(isFizzBuzz([ 1, 2, "Fizz", 4 ])).toBe(true); + expect(isFizzBuzz([ 1, 2, 3, 4 ])).toBe(false); + expect(isFizzBuzz([ 1, 2, "Fizz", 4, "Buzz", 7 ])).toBe(false); + expect( + isFizzBuzz([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + "FizzBuzz", + ]), + ).toBe(false); + expect( + isFizzBuzz([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + "Fizz", + ]), + ).toBe(false); + expect( + isFizzBuzz([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + "Buzz", + ]), + ).toBe(false); + expect( + isFizzBuzz([ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", + 16, + 17, + "Fizz", + 19, + "Buzz", + "Fizz", + 22, + 23, + "Fizz", + "Buzz", + 26, + "Fizz", + 28, + 29, + "FizzBuzz", + 31, + 32, + "Fizz", + 34, + "Buzz", + "Fizz", + 37, + 38, + "Fizz", + "Buzz", + 41, + "Fizz", + 43, + 44, + "FizzBuzz", + 46, + 47, + "Fizz", + 49, + "Buzz", + ]), + ).toBe(true); + }); +}); diff --git a/src/freecodecamp/daily/2025-11-26/main.ts b/src/freecodecamp/daily/2025-11-26/main.ts new file mode 100644 index 0000000..6dc14fe --- /dev/null +++ b/src/freecodecamp/daily/2025-11-26/main.ts @@ -0,0 +1,32 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +const getString = (number: number): string | number => { + if (number % 3 === 0 && number % 5 === 0) { + return "FizzBuzz"; + } + if (number % 3 === 0) { + return "Fizz"; + } + if (number % 5 === 0) { + return "Buzz"; + } + return number; +}; + +/** + * Given an array, determine if it is a correct FizzBuzz sequence from 1 to the last item in the array. + * @param array - The array to check if it is a correct FizzBuzz sequence. + * @returns True if the array is a correct FizzBuzz sequence, false otherwise. + * @see https://www.freecodecamp.org/learn/daily-coding-challenge/2025-11-26 + */ +export const isFizzBuzz = ( + array: Array, +): boolean => { + return array.every((item, index) => { + return item === getString(index + 1); + }); +}; diff --git a/src/freecodecamp/daily/2025-11-27/main.spec.ts b/src/freecodecamp/daily/2025-11-27/main.spec.ts new file mode 100644 index 0000000..9e7f32a --- /dev/null +++ b/src/freecodecamp/daily/2025-11-27/main.spec.ts @@ -0,0 +1,50 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/** + * 1. CalculateAge("2000-11-20") should return 25. + * 2. CalculateAge("2000-12-01") should return 24. + * 3. CalculateAge("2014-10-25") should return 11. + * 4. CalculateAge("1994-01-06") should return 31. + * 5. CalculateAge("1994-12-14") should return 30. + */ + +import { describe, it, expect } from "vitest"; +import { calculateAge } from "./main.js"; + +describe("calculateAge", () => { + it("should return the correct result", () => { + expect(calculateAge("2000-11-20")).toBe(25); + expect(calculateAge("2000-12-01")).toBe(24); + expect(calculateAge("2014-10-25")).toBe(11); + expect(calculateAge("1994-01-06")).toBe(31); + expect(calculateAge("1994-12-14")).toBe(30); + }); + + it("should throw an error if the birthday date is invalid", () => { + expect(() => { + return calculateAge(""); + }).toThrow(TypeError); + expect(() => { + return calculateAge("2000"); + }).toThrow(TypeError); + expect(() => { + return calculateAge("2000-11"); + }).toThrow(TypeError); + expect(() => { + return calculateAge("a-11-11"); + }).toThrow(TypeError); + expect(() => { + return calculateAge("11-b-11"); + }).toThrow(TypeError); + expect(() => { + return calculateAge("11-11-c"); + }).toThrow(TypeError); + expect(() => { + return calculateAge("11-11-11-dfjdalkjfs"); + }).toThrow(TypeError); + }); +}); diff --git a/src/freecodecamp/daily/2025-11-27/main.ts b/src/freecodecamp/daily/2025-11-27/main.ts new file mode 100644 index 0000000..1a9fe17 --- /dev/null +++ b/src/freecodecamp/daily/2025-11-27/main.ts @@ -0,0 +1,51 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/** + * Given the date of someone's birthday in the format YYYY-MM-DD, return the person's age as of November 27th, 2025. + * @param birthday - The date of someone's birthday in the format YYYY-MM-DD. + * @returns The person's age as of November 27th, 2025. + * @throws {TypeError} If the birthday date is invalid. + * @see https://www.freecodecamp.org/learn/daily-coding-challenge/2025-11-27 + */ +export const calculateAge = (birthday: string): number => { + const [ year, month, day ] = birthday.split("-").map(Number); + if ( + year === undefined + || month === undefined + || day === undefined + || Number.isNaN(year) + || Number.isNaN(month) + || Number.isNaN(day) + ) { + throw new TypeError("Invalid birthday date"); + } + + const parsed = new Date(`${birthday}T00:00:00Z`); + if ( + Number.isNaN(parsed.getTime()) + || parsed.getUTCFullYear() !== year + || parsed.getUTCMonth() + 1 !== month + || parsed.getUTCDate() !== day + ) { + throw new TypeError("Invalid birthday date"); + } + + const referenceYear = 2025; + const referenceMonth = 11; + const referenceDay = 27; + + const isLaterMonth = month > referenceMonth; + const isSameMonth = month === referenceMonth; + const isLaterDay = day > referenceDay; + const isLaterDayInSameMonth = isSameMonth && isLaterDay; + const hasUpcomingBirthday = isLaterMonth || isLaterDayInSameMonth; + const birthdayAdjustment = hasUpcomingBirthday + ? 1 + : 0; + + return referenceYear - year - birthdayAdjustment; +};