# artemkorsakov's solution

## to Collatz Conjecture in the Go Track

Published at Jan 31 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

To run the tests run the command `go test` from within the exercise directory.

If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` flags:

``````go test -v --bench . --benchmem
``````

Keep in mind that each reviewer will run benchmarks on a different machine, with different specs, so the results from these benchmark tests may vary.

## Further information

For more detailed information about the Go track, including how to get help if you're having trouble, please visit the exercism.io Go language page.

## 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.

### cases_test.go

``````package collatzconjecture

// Source: exercism/problem-specifications
// Commit: d94e348 collatz-conjecture: fix capitalized description (#1292)
// Problem Specifications Version: 1.2.1

var testCases = []struct {
description string
input       int
expectError bool
expected    int
}{
{
description: "zero steps for one",
input:       1,
expected:    0,
},
{
description: "divide if even",
input:       16,
expected:    4,
},
{
description: "even and odd steps",
input:       12,
expected:    9,
},
{
description: "large number of even and odd steps",
input:       1000000,
expected:    152,
},
{
description: "zero is an error",
input:       0,
expectError: true,
},
{
description: "negative value is an error",
input:       -15,
expectError: true,
},
}``````

### collatz_conjecture_test.go

``````package collatzconjecture

import (
"testing"
)

func TestCollatzConjecture(t *testing.T) {
for _, testCase := range testCases {
steps, err := CollatzConjecture(testCase.input)
if testCase.expectError {
if err == nil {
t.Fatalf("FAIL: %s\n\tCollatzConjecture(%v) expected an error, got %v",
testCase.description, testCase.input, steps)
}
} else {
if err != nil {
t.Fatalf("FAIL: %s\n\tCollatzConjecture(%v) returns unexpected error %s",
testCase.description, testCase.input, err.Error())
}
if steps != testCase.expected {
t.Fatalf("FAIL: %s\n\tCollatzConjecture(%v) expected %v, got %v",
testCase.description, testCase.input, testCase.expected, steps)
}
}
t.Logf("PASS: %s", testCase.description)
}
}

func BenchmarkCollatzConjecture(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, testCase := range testCases {
CollatzConjecture(testCase.input)
}
}
}``````
``````package collatzconjecture

import "errors"

func CollatzConjecture(n int) (int, error) {
if n < 1 {
return 0, errors.New("Invalid input")
}
if n == 1 {
return 0, nil
}
if n%2 == 0 {
res, _ := CollatzConjecture(n / 2);
return res + 1, nil
}
res, _ := CollatzConjecture(3*n + 1);
return res + 1, nil
}``````