Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions Maths/CollatzSequence.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
/**
* @function collatz
* @description Applies the Collatz Sequence on a specified number.
* The Collatz Sequence states that every natural number will always fall in a 1, 2, 4 loop when iterated under the following function:
* If the number is even, divide by 2, and if its odd, multiply it by 3 and add 1.
*
* @parama {Integer} n The number to apply the Collatz Sequence to.
*
* @return An array of steps and the final result..
*
* @see [Collatz Conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture)
*
* @example collatz(1) = { result: 1, steps: [] }
* @example collatz(5) = { result: 1, steps: [16, 8, 4, 2, 1] }
* @function collatzSequence
* @description The Collatz conjecture states that for any positive integer n,
* if n is even divide by 2, if n is odd multiply by 3 and add 1.
* Repeating this process will eventually reach 1.
* This function returns the full Collatz sequence for a given number.
* @param {number} n - A positive integer
* @returns {number[]} - The Collatz sequence starting from n
* @see https://en.wikipedia.org/wiki/Collatz_conjecture
* @example collatzSequence(6) => [6, 3, 10, 5, 16, 8, 4, 2, 1]
* @example collatzSequence(1) => [1]
*/
export function collatz(n) {
const steps = []

while (n !== 1) {
if (n % 2 === 0) {
n = n / 2
} else {
n = 3 * n + 1
}

steps.push(n)
const collatzSequence = (n) => {
if (!Number.isInteger(n) || n < 1) {
throw new TypeError('Input must be a positive integer')
}

return { result: n, steps }
const sequence = [n]
let current = n
while (current !== 1) {
current = current % 2 === 0 ? current / 2 : 3 * current + 1
sequence.push(current)
}
return sequence
}

export { collatzSequence }
50 changes: 45 additions & 5 deletions Maths/test/CollatzSequence.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
import { collatz } from '../CollatzSequence'
import { collatzSequence } from '../CollatzSequence.js'

describe('The Collatz Sequence', () => {
it('Should be 1', () => {
expect(collatz(1)).toStrictEqual({ result: 1, steps: [] })
expect(collatz(5)).toStrictEqual({ result: 1, steps: [16, 8, 4, 2, 1] })
describe('collatzSequence', () => {
test('collatzSequence(1) returns [1]', () => {
expect(collatzSequence(1)).toEqual([1])
})

test('collatzSequence(2) returns [2, 1]', () => {
expect(collatzSequence(2)).toEqual([2, 1])
})

test('collatzSequence(6) returns correct sequence', () => {
expect(collatzSequence(6)).toEqual([6, 3, 10, 5, 16, 8, 4, 2, 1])
})

test('collatzSequence always ends with 1', () => {
const seq = collatzSequence(27)
expect(seq[seq.length - 1]).toBe(1)
})

test('collatzSequence(1) has length 1', () => {
expect(collatzSequence(1)).toHaveLength(1)
})

test('collatzSequence starts with input number', () => {
expect(collatzSequence(10)[0]).toBe(10)
})

test('collatzSequence(4) returns [4, 2, 1]', () => {
expect(collatzSequence(4)).toEqual([4, 2, 1])
})

test('collatzSequence(5) returns [5, 16, 8, 4, 2, 1]', () => {
expect(collatzSequence(5)).toEqual([5, 16, 8, 4, 2, 1])
})

test('throws TypeError for zero', () => {
expect(() => collatzSequence(0)).toThrow(TypeError)
})

test('throws TypeError for negative input', () => {
expect(() => collatzSequence(-6)).toThrow(TypeError)
})

test('throws TypeError for float input', () => {
expect(() => collatzSequence(6.5)).toThrow(TypeError)
})
})
Loading