 # michaeldperez's solution

## to Collatz Conjecture in the PHP Track

Published at Sep 07 2019 · 0 comments
Instructions
Test suite
Solution

The Collatz Conjecture or 3x+1 problem can be summarized as follows:

Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely. The conjecture states that no matter which number you start with, you will always reach 1 eventually.

Given a number n, return the number of steps required to reach 1.

## Examples

Starting with n = 12, the steps would be as follows:

1. 12
2. 6
3. 3
4. 10
5. 5
6. 16
7. 8
8. 4
9. 2
10. 1

Resulting in 9 steps. So for input n = 12, the return value would be 9.

## Running the tests

1. Go to the root of your PHP exercise directory, which is `<EXERCISM_WORKSPACE>/php`. To find the Exercism workspace run

`````` % exercism debug | grep Workspace
``````
2. Get PHPUnit if you don't have it already.

`````` % wget --no-check-certificate https://phar.phpunit.de/phpunit.phar
% chmod +x phpunit.phar
``````
3. Execute the tests:

`````` % ./phpunit.phar collatz-conjecture/collatz-conjecture_test.php
``````

## Source

An unsolved problem in mathematics named after mathematician Lothar Collatz https://en.wikipedia.org/wiki/3x_%2B_1_problem

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### collatz-conjecture_test.php

``````<?php

class CollatzConjecture extends PHPUnit\Framework\TestCase
{
public static function setUpBeforeClass() : void
{
require_once 'collatz-conjecture.php';
}

public function testZeroStepsForOne() : void
{
\$this->assertEquals(0, steps(1));
}

public function testDivideIfEven() : void
{
\$this->assertEquals(4, steps(16));
}

public function testEvenAndOddSteps() : void
{
\$this->assertEquals(9, steps(12));
}

public function testLargeNumberOfEvenAndOddSteps() : void
{
\$this->assertEquals(152, steps(1000000));
}

public function testZeroIsAnError() : void
{
\$this->expectException(InvalidArgumentException::class);
\$this->expectExceptionMessage('Only positive numbers are allowed');

steps(0);
}

public function testNegativeValueIsAnError() : void
{
\$this->expectException(InvalidArgumentException::class);
\$this->expectExceptionMessage('Only positive numbers are allowed');

steps(-1);
}
}``````
``````<?php

function steps(int \$n): int
{
if (\$n < 1)
{
throw new InvalidArgumentException(
'Only positive numbers are allowed'
);
}

\$steps = 0;

while (\$n !== 1)
{
\$n = \$n % 2 === 0
? \$n / 2
: \$n * 3 + 1;

\$steps++;
}
return \$steps;
}``````