diff --git a/maths/collatz_sequence.ts b/maths/collatz_sequence.ts new file mode 100644 index 00000000..fff660be --- /dev/null +++ b/maths/collatz_sequence.ts @@ -0,0 +1,36 @@ +/** + * Generates the Collatz sequence for a given positive integer. + * + * The Collatz conjecture sequence is defined as follows: + * - Start with any positive integer `n`. + * - If `n` is even, divide it by 2. + * - If `n` is odd, multiply it by 3 and add 1. + * - Repeat the process with the new value of `n` until `n` equals 1. + * + * @param n - A positive integer to generate the Collatz sequence. + * @throws {Error} - Throws an error if `n` is not a positive integer. + * @returns {number[]} - The Collatz sequence starting from `n`. + * + * @example + * collatzSequence(5); // Returns: [5, 16, 8, 4, 2, 1] + * collatzSequence(10); // Returns: [10, 5, 16, 8, 4, 2, 1] + */ +export const collatzSequence = (n: number): number[] => { + if (n <= 0 || !Number.isInteger(n)) { + throw new Error('Sequence only defined for positive integers.') + } + + const result: number[] = [] + + while (n !== 1) { + result.push(n) + if (n % 2 === 0) { + n /= 2 + } else { + n = n * 3 + 1 + } + } + + result.push(1) + return result +} diff --git a/maths/test/collatz_sequence.test.ts b/maths/test/collatz_sequence.test.ts new file mode 100644 index 00000000..2f65508e --- /dev/null +++ b/maths/test/collatz_sequence.test.ts @@ -0,0 +1,39 @@ +import { collatzSequence } from '../collatz_sequence' + +describe('collatzSequence', () => { + test('should generate the correct Collatz sequence for n = 5', () => { + const result = collatzSequence(5) + expect(result).toEqual([5, 16, 8, 4, 2, 1]) + }) + + test('should generate the correct Collatz sequence for n = 1', () => { + const result = collatzSequence(1) + expect(result).toEqual([1]) + }) + + test('should handle large inputs correctly (n = 27)', () => { + const result = collatzSequence(27) + // The exact sequence for n = 27 is very long; check key parts + expect(result[0]).toBe(27) + expect(result[result.length - 1]).toBe(1) + expect(result.length).toBeGreaterThan(100) + }) + + test('should throw an error for n = 0', () => { + expect(() => collatzSequence(0)).toThrow( + 'Sequence only defined for positive integers.' + ) + }) + + test('should throw an error for negative inputs (n = -5)', () => { + expect(() => collatzSequence(-5)).toThrow( + 'Sequence only defined for positive integers.' + ) + }) + + test('should throw an error for non-integer inputs (n = 5.5)', () => { + expect(() => collatzSequence(5.5)).toThrow( + 'Sequence only defined for positive integers.' + ) + }) +})