From 178846dd9872cf302de3a2fa7cab30d28a7e1dfd Mon Sep 17 00:00:00 2001 From: sarthakgupta1907-cell Date: Fri, 6 Nov 2026 11:11:36 +0530 Subject: [PATCH] feat: add array shuffle algorithm --- Data-Structures/Array/Shuffle.js | 22 ++++++++++ Data-Structures/Array/test/Shuffle.test.js | 47 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 Data-Structures/Array/Shuffle.js create mode 100644 Data-Structures/Array/test/Shuffle.test.js diff --git a/Data-Structures/Array/Shuffle.js b/Data-Structures/Array/Shuffle.js new file mode 100644 index 0000000000..01341a7a64 --- /dev/null +++ b/Data-Structures/Array/Shuffle.js @@ -0,0 +1,22 @@ +/** + * @function shuffle + * @description Randomly shuffles the elements of an array using the + * Fisher-Yates (Knuth) shuffle algorithm. + * @param {Array} arr - The input array to shuffle + * @returns {Array} - A new shuffled array + * @see https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * @example shuffle([1, 2, 3, 4, 5]) => [3, 1, 5, 2, 4] (random order) + */ +const shuffle = (arr) => { + if (!Array.isArray(arr)) { + throw new TypeError('Input must be an array') + } + const result = [...arr] + for (let i = result.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[result[i], result[j]] = [result[j], result[i]] + } + return result +} + +export { shuffle } diff --git a/Data-Structures/Array/test/Shuffle.test.js b/Data-Structures/Array/test/Shuffle.test.js new file mode 100644 index 0000000000..5c31065712 --- /dev/null +++ b/Data-Structures/Array/test/Shuffle.test.js @@ -0,0 +1,47 @@ +import { shuffle } from '../Shuffle.js' + +describe('shuffle', () => { + test('shuffle returns array of same length', () => { + expect(shuffle([1, 2, 3, 4, 5])).toHaveLength(5) + }) + + test('shuffle contains all original elements', () => { + const arr = [1, 2, 3, 4, 5] + const result = shuffle(arr) + expect(result.sort()).toEqual([...arr].sort()) + }) + + test('shuffle empty array returns empty array', () => { + expect(shuffle([])).toEqual([]) + }) + + test('shuffle single element returns same array', () => { + expect(shuffle([1])).toEqual([1]) + }) + + test('shuffle does not mutate original array', () => { + const arr = [1, 2, 3, 4, 5] + shuffle(arr) + expect(arr).toEqual([1, 2, 3, 4, 5]) + }) + + test('shuffle works with strings', () => { + const arr = ['a', 'b', 'c', 'd'] + const result = shuffle(arr) + expect(result.sort()).toEqual([...arr].sort()) + }) + + test('shuffle returns a new array', () => { + const arr = [1, 2, 3] + const result = shuffle(arr) + expect(result).not.toBe(arr) + }) + + test('throws TypeError for non-array input', () => { + expect(() => shuffle('123')).toThrow(TypeError) + }) + + test('throws TypeError for null input', () => { + expect(() => shuffle(null)).toThrow(TypeError) + }) +})