Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collatz-conjecture #593

Merged
merged 16 commits into from
Sep 20, 2017
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@
"topics": [
]
},
{
"uuid": "6eba4eac-8395-4ad6-ac21-3651a11ab4b4",
"slug": "collatz-conjecture",
"core": false,
"unlocked_by": null,
"difficulty": 1,
"topics": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this exercise now uses Maybe, please add it to the topics list (see "rna-transcription" for example of how it is done)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

]
},
{
"uuid": "85d77b8e-9b87-4d02-9fba-81f843bd66f1",
"slug": "rna-transcription",
Expand Down
86 changes: 86 additions & 0 deletions exercises/collatz-conjecture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Collatz Conjecture.

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:

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

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

## Getting Started

For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/haskell).

## Running the tests

To run the test suite, execute the following command:

```bash
stack test
```

#### If you get an error message like this...

```
No .cabal file found in directory
```

You are probably running an old stack version and need
to upgrade it.

#### Otherwise, if you get an error message like this...

```
No compiler found, expected minor version match with...
Try running "stack setup" to install the correct GHC...
```

Just do as it says and it will download and install
the correct compiler version:

```bash
stack setup
```

## Running *GHCi*

If you want to play with your solution in GHCi, just run the command:

```bash
stack ghci
```

## Feedback, Issues, Pull Requests

The [exercism/haskell](https://github.com/exercism/haskell) repository on
GitHub is the home for all of the Haskell exercises.

If you have feedback about an exercise, or want to help implementing a new
one, head over there and create an issue. We'll do our best to help you!

## Source

An unsolved problem in mathematics named after mathematician Lothar Collatz
see more at [collatz conjecture wikipedia]("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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: collatz-conjecture

dependencies:
- base

library:
exposed-modules: CollatzConjecture
source-dirs: src

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- collatz-conjecture
- hspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module CollatzConjecture (collatz) where

collatzHelper :: Integer -> Integer -> Maybe Integer
collatzHelper t x | x == 1 = Just t
| even x = collatzHelper (t+1) (x `div` 2)
| otherwise = collatzHelper (t+1) (x*3 + 1)

collatz :: Integer -> Maybe Integer
collatz x = if x <= 0 then Nothing else collatzHelper 0 x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are two spaces after the if, you could remove one of them, right?

20 changes: 20 additions & 0 deletions exercises/collatz-conjecture/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: collatz-conjecture
version: 1.1.1.1

dependencies:
- base

library:
exposed-modules: CollatzConjecture
source-dirs: src
dependencies:
# - foo # List here the packages you
# - bar # want to use in your solution.

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- collatz-conjecture
- hspec
4 changes: 4 additions & 0 deletions exercises/collatz-conjecture/src/CollatzConjecture.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module CollatzConjecture (collatz) where

collatz :: Integer -> Maybe Integer
collatz = error "You need to implement this function."
1 change: 1 addition & 0 deletions exercises/collatz-conjecture/stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resolver: lts-8.21
59 changes: 59 additions & 0 deletions exercises/collatz-conjecture/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this line is necessary. Can you check? If you confirm it is not necessary, please send a PR that deletes it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retract. I think #144 tells me it is desirable to have for exercises with numbers.

{-# LANGUAGE RecordWildCards #-}

import Data.Foldable (for_)
import Test.Hspec (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import CollatzConjecture (collatz)

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = describe "collatz" $ for_ cases test
where

test Case{..} = it description assertion
where
assertion = collatz number `shouldBe` expected


data Case = Case { description :: String
, property :: String
, number :: Integer
, expected :: Maybe Integer
}

cases :: [Case]
cases = [ Case { description = "zero steps for one"
, property = "steps"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the property is not being used. It should be removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be in problem-specifications since it tells what is being tested.

It must not be here since we already know what we are testing (it's specified in code)

, number = 1
, expected = Just 0
}
, Case { description = "divide if even"
, property = "steps"
, number = 16
, expected = Just 4
}
, Case { description = "even and odd steps"
, property = "steps"
, number = 12
, expected =Just 9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a space after the = here?

}
, Case { description = "Large number of even and odd steps"
, property = "steps"
, number = 1000000
, expected = Just 152
}
, Case { description = "zero is an error"
, property = "steps"
, number = 0
, expected = Nothing
}
, Case { description = "negative value is an error"
, property = "steps"
, number = -15
, expected = Nothing
}
]