Search code examples
haskellfunctional-programming

Haskell modified hamming so that the input is a list instead of 1


So this would be the standard hamming code for Haskell, I managed to understand and write it.

merge :: Ord a =>[a] -> [a] -> [a] 
merge [] ys = ys
merge xs [] = xs
merge (x : xs) (y : ys) 
    | x == y    = x : merge xs ys
    | x < y     = x : merge xs (y : ys)
    | otherwise = y : merge (x:xs) ys

hamming :: [Integer]
hamming = 1: merge (map (2 *) hamming)
                  (merge (map (3 *) hamming)
                         (map (5 *) hamming))

Now i'm trying to create a modified hamming code which has a list as input ( instead of 1 like in the standard hamming code ) .

Example would be print take 10 modifiedhamming [10,30,50] with the output [10,20,30,40,50,60,80,90,100, 120] . Sadly i can't manage to make it generate next elements after it multiplies the initial list with 2, 3 and 5.

This is what I tried :

hammingCode :: [Integer] -> [Integer]
hammingCode a  =    merge    ( map (*2) a)
                             (merge (map (*3) a)
                                    (merge a (map (*5) a)))

main = print (take 20 (hammingCode [10, 20, 50]))  

with the output : [10,20,30,40,50,60,100,150,250] . As stated before this will just multiply the initial list with each element

I also tried this but i get a stack overflow error

hammingCode2 xs = merge xs (merge (map (*2) hammings) (merge (map (*3) hammings) (map (*5) hammings)))
  where
    hammings = hammingCode2 xs

I've tried solving this by reading through different functional programming books and even with chatgpt and bard and still didn't manage to solve it .


Solution

  • Hint: a modest change to your hamming function would allow you to generate a list of all needed multiples starting with any single Integer:

    hamming2 :: Integer -> [Integer]
    hamming2 x = ham
      where ham = x : merge (map (2 *) ham)
                          (merge (map (3 *) ham)
                                 (map (5 *) ham))
    

    If you were to map hamming2 over a list like [10,30,50], that would give you a list of three lists that can be merged together to get all of the required multiples.