Even if you can only use basic functions, it still helps if you can decompose the problem into smaller problems. Based on the OP and the comments thread, it seems that these three requirements must be fulfilled:
- Calculate a number based on a previous number
- Generate a list where the next element is based on the previous element
- Stop generating when a duplicate is encountered
I'd suggest solving each of these problems independently of each other, and then combining the solutions.
Calculate the next number
At first glance, this seems to be the heart of the problem. This is where you need to detect whether the number is even or odd, and calculate a result accordingly. Implement this as a function that you could call, say, calcNext. It needs to have a type like this:
Prelude> :t calcNext
calcNext :: Integral a => a -> a
With it, you can calculate the next number based on any input:
Prelude> calcNext 9
26
Prelude> calcNext 26
13
Prelude> calcNext 13
38
Prelude> calcNext 38
19
I'll leave the implementation of calcNext as an exercise.
Generate a list
Sometimes, it can be helpful to look for existing functions. Perhaps there's already a function that can be used to generate a list from a function like calcNext.
One way to look for such functions is to use Hoogle.
Making a guess and typing (a -> a) -> [a] into the search field on Hoogle yields a number of results, among which is iterate, which has the similar (but not identical) type of (a -> a) -> a -> [a]. That seems to be close enough, because it enables you to kick off list generation like this:
Prelude> take 10 $ iterate calcNext 9
[9,26,13,38,19,56,28,14,7,20]
Here I chose to take 10 because iterate will go on forever.
The order here is reversed compared to the OP, but I'll leave it as another exercise to reverse a (finite) list, if the order matters.
If you want to base a solution entirely on functions you wrote yourself, you can try to implement your own iterate function. If you need a hint, then you can always peek at the source code of the built-in iterate function - it's open source.
Stop on duplicate
This one is probably the trickiest part, since you need to 'remember' all the previous elements. What you can do is to create a function that not only calculates the next element, but also keeps a list of all previous elements around. You could write a wrapper function around calcNext that has a type like this:
Prelude> :t calcNextAcc
calcNextAcc :: Integral a => (a, [a]) -> (a, [a])
Since this function still returns the same type as its input, you can still use it with iterate:
Prelude> take 15 $ iterate calcNextAcc (9, [])
[(9,[]),(26,[9]),(13,[26,9]),(38,[13,26,9]),(19,[38,13,26,9]),(56,[19,38,13,26,9]),
(28,[56,19,38,13,26,9]),(14,[28,56,19,38,13,26,9]),(7,[14,28,56,19,38,13,26,9]),
(20,[7,14,28,56,19,38,13,26,9]),(10,[20,7,14,28,56,19,38,13,26,9]),
(5,[10,20,7,14,28,56,19,38,13,26,9]),(14,[5,10,20,7,14,28,56,19,38,13,26,9]),
(7,[14,5,10,20,7,14,28,56,19,38,13,26,9]),(20,[7,14,5,10,20,7,14,28,56,19,38,13,26,9])]
Notice how the second element of each tuple contains all elements calculated so far. Now you just need to go look for duplicates.
You could, for example, write a function called containsDuplicates with this type:
Prelude> :t containsDuplicates
containsDuplicates :: Eq a => [a] -> Bool
With that, you can use a function like the built-in takeWhile to iterate until you find a duplicate:
Prelude> takeWhile (not . containsDuplicates . snd) $ iterate calcNextAcc (9, [])
[(9,[]),(26,[9]),(13,[26,9]),(38,[13,26,9]),(19,[38,13,26,9]),(56,[19,38,13,26,9]),
(28,[56,19,38,13,26,9]),(14,[28,56,19,38,13,26,9]),(7,[14,28,56,19,38,13,26,9]),
(20,[7,14,28,56,19,38,13,26,9]),(10,[20,7,14,28,56,19,38,13,26,9]),
(5,[10,20,7,14,28,56,19,38,13,26,9]),(14,[5,10,20,7,14,28,56,19,38,13,26,9])]
The last element there contains your solution:
Prelude> last $ takeWhile (not . containsDuplicates . snd) $ iterate calcNextAcc (9, [])
(14,[5,10,20,7,14,28,56,19,38,13,26,9])
You can easily turn that tuple into a list:
Prelude> uncurry (:) $ last $ takeWhile (not . containsDuplicates . snd) $ iterate calcNextAcc (9, [])
[14,5,10,20,7,14,28,56,19,38,13,26,9]
I've left the implementation of the various functions as an exercise.
9 `elem` [9] = [9]so it just returns[9]26instead of28?9is odd, so9*3+1=28? Am I missing something?