From 63750e566406ff880680998952e1105ddd33b03d Mon Sep 17 00:00:00 2001 From: James Walker Date: Wed, 15 Sep 2021 18:21:26 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20haskell:=20collatz-conjecture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- haskell/collatz-conjecture/HELP.md | 88 +++++++++++++++++++ haskell/collatz-conjecture/README.md | 48 ++++++++++ .../examples/success-standard/package.yaml | 16 ++++ haskell/collatz-conjecture/package.yaml | 21 +++++ .../src/CollatzConjecture.hs | 10 +++ haskell/collatz-conjecture/stack.yaml | 1 + haskell/collatz-conjecture/test/Tests.hs | 54 ++++++++++++ 7 files changed, 238 insertions(+) create mode 100644 haskell/collatz-conjecture/HELP.md create mode 100644 haskell/collatz-conjecture/README.md create mode 100644 haskell/collatz-conjecture/examples/success-standard/package.yaml create mode 100644 haskell/collatz-conjecture/package.yaml create mode 100644 haskell/collatz-conjecture/src/CollatzConjecture.hs create mode 100644 haskell/collatz-conjecture/stack.yaml create mode 100644 haskell/collatz-conjecture/test/Tests.hs diff --git a/haskell/collatz-conjecture/HELP.md b/haskell/collatz-conjecture/HELP.md new file mode 100644 index 0000000..ec52839 --- /dev/null +++ b/haskell/collatz-conjecture/HELP.md @@ -0,0 +1,88 @@ +# Help + +## 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 +``` + +or + +``` +RedownloadInvalidResponse Request { +... +} + "/home/username/.stack/build-plan/lts-xx.yy.yaml" (Response {responseStatus = Status {statusCode = 404, statusMessage = "Not Found"}, +``` + +You are probably running an old stack version and need +to upgrade it. Try running: + +```bash +stack upgrade +``` + +Or see other options for upgrading at [Stack documentation](https://docs.haskellstack.org/en/stable/install_and_upgrade/#upgrade). + +#### 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 +``` + + +If you want to play with your solution in GHCi, just run the command: + +```bash +stack ghci +``` + +## Submitting your solution + +You can submit your solution using the `exercism submit src/CollatzConjecture.hs` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Haskell track's documentation](https://exercism.org/docs/tracks/haskell) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +## Getting Started + +Please refer to the [installation](https://exercism.io/tracks/haskell/installation) +and [learning](https://exercism.io/tracks/haskell/learning) help pages. + +## 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! +{{ with .Spec.Credits }} \ No newline at end of file diff --git a/haskell/collatz-conjecture/README.md b/haskell/collatz-conjecture/README.md new file mode 100644 index 0000000..b43b39e --- /dev/null +++ b/haskell/collatz-conjecture/README.md @@ -0,0 +1,48 @@ +# Collatz Conjecture + +Welcome to Collatz Conjecture on Exercism's Haskell Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## Instructions + +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. + +## Source + +### Contributed to by + +- @guygastineau +- @iHiD +- @navossoc +- @petertseng +- @ppartarr +- @sshine +- @tejasbubane + +### Based on + +An unsolved problem in mathematics named after mathematician Lothar Collatz - https://en.wikipedia.org/wiki/3x_%2B_1_problem \ No newline at end of file diff --git a/haskell/collatz-conjecture/examples/success-standard/package.yaml b/haskell/collatz-conjecture/examples/success-standard/package.yaml new file mode 100644 index 0000000..26631e8 --- /dev/null +++ b/haskell/collatz-conjecture/examples/success-standard/package.yaml @@ -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 diff --git a/haskell/collatz-conjecture/package.yaml b/haskell/collatz-conjecture/package.yaml new file mode 100644 index 0000000..b1e699e --- /dev/null +++ b/haskell/collatz-conjecture/package.yaml @@ -0,0 +1,21 @@ +name: collatz-conjecture +version: 1.2.1.4 + +dependencies: + - base + +library: + exposed-modules: CollatzConjecture + source-dirs: src + ghc-options: -Wall + # 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 diff --git a/haskell/collatz-conjecture/src/CollatzConjecture.hs b/haskell/collatz-conjecture/src/CollatzConjecture.hs new file mode 100644 index 0000000..046ffa7 --- /dev/null +++ b/haskell/collatz-conjecture/src/CollatzConjecture.hs @@ -0,0 +1,10 @@ +module CollatzConjecture (collatz) where + +collatz :: Integer -> Maybe Integer +collatz n = if n <= 0 then Nothing else step 0 n + +step :: Integer -> Integer -> Maybe Integer +step count n + | n == 1 = Just count + | even n = step (count + 1) (n `div` 2) + | otherwise = step (count + 1) (3 * n + 1) diff --git a/haskell/collatz-conjecture/stack.yaml b/haskell/collatz-conjecture/stack.yaml new file mode 100644 index 0000000..35c2e5b --- /dev/null +++ b/haskell/collatz-conjecture/stack.yaml @@ -0,0 +1 @@ +resolver: lts-16.21 diff --git a/haskell/collatz-conjecture/test/Tests.hs b/haskell/collatz-conjecture/test/Tests.hs new file mode 100644 index 0000000..369b69c --- /dev/null +++ b/haskell/collatz-conjecture/test/Tests.hs @@ -0,0 +1,54 @@ +{-# OPTIONS_GHC -fno-warn-type-defaults #-} +{-# 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 + , number :: Integer + , expected :: Maybe Integer + } + +cases :: [Case] +cases = [ Case { description = "zero steps for one" + , number = 1 + , expected = Just 0 + } + , Case { description = "divide if even" + , number = 16 + , expected = Just 4 + } + , Case { description = "even and odd steps" + , number = 12 + , expected = Just 9 + } + , Case { description = "large number of even and odd steps" + , number = 1000000 + , expected = Just 152 + } + , Case { description = "zero is an error" + , number = 0 + , expected = Nothing + } + , Case { description = "negative value is an error" + , number = -15 + , expected = Nothing + } + ] + +-- 553e2f7a6ce638a6cf622985b9138e6013626eb3