diff --git a/eslint.config.js b/eslint.config.js index 0ad010b..87c488a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -8,6 +8,7 @@ export default [ "max-depth": "off", "max-statements": "off", "complexity": "off", + "unicorn/no-array-reduce": "off", }, }, { diff --git a/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.spec.ts b/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.spec.ts new file mode 100644 index 0000000..eddbc4e --- /dev/null +++ b/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.spec.ts @@ -0,0 +1,25 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { describe, it, expect } from "vitest"; +import { mutation } from "./main.js"; + +describe("mutation", () => { + it("should return the correct result", () => { + expect(mutation([ "hello", "hey" ])).toBe(false); + expect(mutation([ "hello", "Hello" ])).toBe(true); + expect(mutation([ "zyxwvutsrqponmlkjihgfedcba", "qrstu" ])).toBe(true); + expect(mutation([ "Mary", "Army" ])).toBe(true); + expect(mutation([ "Mary", "Aarmy" ])).toBe(true); + expect(mutation([ "Alien", "line" ])).toBe(true); + expect(mutation([ "floor", "for" ])).toBe(true); + expect(mutation([ "hello", "neo" ])).toBe(false); + expect(mutation([ "voodoo", "no" ])).toBe(false); + expect(mutation([ "ate", "date" ])).toBe(false); + expect(mutation([ "Tiger", "Zebra" ])).toBe(false); + expect(mutation([ "Noel", "Ole" ])).toBe(true); + }); +}); diff --git a/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.ts b/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.ts new file mode 100644 index 0000000..655a6e2 --- /dev/null +++ b/src/freecodecamp/curriculum/implement-the-mutations-algorithm/main.ts @@ -0,0 +1,21 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/** + * Determines if the second string can be constructed from only the letters found in the first string. + * @param array - An array containing two strings. + * @param array."0" - The first string. + * @param array."1" - The second string. + * @returns True if the second string can be constructed from only the letters found in the first string, false otherwise. + * @see https://www.freecodecamp.org/learn/javascript-v9/lab-mutations/implement-the-mutations-algorithm + */ +export const mutation = ([ first, second ]: [ string, string ]): boolean => { + return [ ...second. + toLowerCase() ]. + every((letter) => { + return first.toLowerCase().includes(letter); + }); +}; diff --git a/src/freecodecamp/daily/2025-11-23/main.spec.ts b/src/freecodecamp/daily/2025-11-23/main.spec.ts new file mode 100644 index 0000000..7752a25 --- /dev/null +++ b/src/freecodecamp/daily/2025-11-23/main.spec.ts @@ -0,0 +1,54 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { describe, it, expect } from "vitest"; +import { countCharacters } from "./main.js"; + +describe("countCharacters", () => { + it("should return the correct count of characters", () => { + expect(countCharacters("hello world")).toStrictEqual([ + "d 1", + "e 1", + "h 1", + "l 3", + "o 2", + "r 1", + "w 1", + ]); + expect(countCharacters("I love coding challenges!")).toStrictEqual([ + "a 1", + "c 2", + "d 1", + "e 3", + "g 2", + "h 1", + "i 2", + "l 3", + "n 2", + "o 2", + "s 1", + "v 1", + ]); + expect( + countCharacters("// TODO: Complete this challenge ASAP!"), + ).toStrictEqual([ + "a 3", + "c 2", + "d 1", + "e 4", + "g 1", + "h 2", + "i 1", + "l 3", + "m 1", + "n 1", + "o 3", + "p 2", + "s 2", + "t 3", + ]); + }); +}); diff --git a/src/freecodecamp/daily/2025-11-23/main.ts b/src/freecodecamp/daily/2025-11-23/main.ts new file mode 100644 index 0000000..350bece --- /dev/null +++ b/src/freecodecamp/daily/2025-11-23/main.ts @@ -0,0 +1,25 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/** + * Given a sentence string, return an array with a count of each character in alphabetical order. + * @param sentence - The sentence to count the characters in. + * @returns An object with the number of characters in the sentence. + * @see https://www.freecodecamp.org/learn/daily-coding-challenge/2025-11-23 + */ +export const countCharacters = (sentence: string): Array => { + return Object.entries([ ...sentence.toLowerCase().replaceAll(/[^a-z]/g, "") ]. + reduce((accumulator, char): Record => { + accumulator[char] = (accumulator[char] ?? 0) + 1; + return accumulator; + }, {})). + map(([ char, count ]) => { + return `${char} ${count.toString()}`; + }). + sort((a, b) => { + return a.localeCompare(b); + }); +}; diff --git a/src/freecodecamp/daily/2025-11-24/main.spec.ts b/src/freecodecamp/daily/2025-11-24/main.spec.ts new file mode 100644 index 0000000..5c64a4a --- /dev/null +++ b/src/freecodecamp/daily/2025-11-24/main.spec.ts @@ -0,0 +1,28 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +import { describe, it, expect } from "vitest"; +import { validateMessage } from "./main.js"; + +describe("validateMessage", () => { + it("should return the correct validation result", () => { + expect(validateMessage("hello world", "hw")).toBe(true); + expect(validateMessage("ALL CAPITAL LETTERS", "acl")).toBe(true); + expect(validateMessage("Coding challenge are boring.", "cca")).toBe(false); + expect( + validateMessage( + "The quick brown fox jumps over the lazy dog.", + "TQBFJOTLD", + ), + ).toBe(true); + expect( + validateMessage( + "The quick brown fox jumps over the lazy dog.", + "TQBFJOTLDT", + ), + ).toBe(false); + }); +}); diff --git a/src/freecodecamp/daily/2025-11-24/main.ts b/src/freecodecamp/daily/2025-11-24/main.ts new file mode 100644 index 0000000..4ee38cb --- /dev/null +++ b/src/freecodecamp/daily/2025-11-24/main.ts @@ -0,0 +1,28 @@ +/** + * @copyright NHCarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/** + * Given a message string and a validation string, determine if the message is valid. + * @param message - The message to validate. + * @param validator - The validator to use. + * @returns True if the message is valid, false otherwise. + * @see https://www.freecodecamp.org/learn/daily-coding-challenge/2025-11-24 + */ +export const validateMessage = ( + message: string, + validator: string, +): boolean => { + const messageLetters = message. + toLowerCase(). + split(/\s+/g). + map((word) => { + return word[0]; + }); + const validatorLetters = [ ...validator.toLowerCase() ]; + return messageLetters.every((letter, index) => { + return letter === validatorLetters[index]; + }) && messageLetters.length === validatorLetters.length; +};