Skip to content

Instantly share code, notes, and snippets.

@throughnothing
Last active August 14, 2018 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save throughnothing/5b73c0576890e5228fd46f3898445be2 to your computer and use it in GitHub Desktop.
Save throughnothing/5b73c0576890e5228fd46f3898445be2 to your computer and use it in GitHub Desktop.
Collatz Purescript
module Collatz where
import Prelude (div, otherwise, (==), (*), (+), (>), ($), map)
import Data.Array (length)
import Data.Ord (class Ord)
import Data.Semiring (class Semiring, zero)
import Data.Functor (class Functor)
import Data.Int (even)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Data.Unfoldable (class Unfoldable, unfoldr)
import Data.Foldable (foldr, class Foldable)
-- Imports only for the run function
import Prelude (Unit)
import Effect (Effect)
import Data.List.Lazy (List, range)
import Effect.Console (logShow)
collatz :: Int -> Int
collatz n
| even n = div n 2
| otherwise = 3 * n + 1
collatzList :: ∀ f. Unfoldable f => Int -> f Int
collatzList = unfoldr next
where
next n | n == 0 = Nothing
| n == 1 = Just (Tuple 1 0)
| otherwise = Just $ Tuple n $ collatz n
collatzLengths :: ∀ f. Functor f => f Int -> f (Tuple Int Int)
collatzLengths = map (\n -> Tuple n (length (collatzList n :: Array Int)))
findMax :: ∀ f a. Foldable f => Ord a => Semiring a => f (Tuple a a) -> Tuple a a
findMax = foldr go $ Tuple zero zero
where go (Tuple n l) (Tuple n' l') | l' > l = Tuple n' l'
| otherwise = Tuple n l
-- | Run with: time node -e 'require("./output/Collatz/index.js").main(1)(100000)()'
main :: Int -> Int -> Effect Unit
main s e = do
logShow $ findMax $ collatzLengths (range s e) :: List (Tuple Int Int)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment