воскресенье, 13 марта 2016 г.

Harmonic series

This is the very simple interview question: check that series are harmonic, i.e. list of numbers are line (kx + b) - two close elements always have the same difference (k).

Naive implementation is:

-- Naive version of checking if sequence of numbers are harmonic (difference
-- between neighbords is the const)

-- Folding function with args (prev, diff, result)
rf (p, d, Nothing) c = (c, d', Just True) where d' = c - p
rf (p, d, Just False) c = (c, d, Just False)
rf (p, d, Just True) c = (c, d', Just $ d == d') where d' = c - p

harm [] = False
harm (hd:xs) = let (_, _, Just x) = foldl rf (hd, 0, Nothing) xs in x


main = do
  print $ harm [1, 2, 3, 4, 5, 6, 9]
  print $ harm [1, 2, 3, 4, 5, 6]
  print $ harm [2, 4, 6, 8]

where we are folding items and keep on each step tuple (prev, diff, result), where result is Just True, Just False or Nothing on first item. Actually this code has problem: it can not process harm [2] or harm [].

Another version may calculate difference between neighboards and then to calculate difference in the same way again:

1    2    3    4    6
  -1   -1   -1   -2
     0    0   -1!

After it we can summarize all items and if result is 0 then we have harmonic numbers:

neighOp op [] = []
neighOp op l@(hd:xs) = zipWith op l xs

harm [] = False
harm [x] = False
harm ns = 0 == (foldl1 (+) $ neighOp (-) $ (neighOp (-) ns))


main = do
  print $ harm [1, 2, 3, 4, 5, 6, 9]
  print $ harm [1, 2, 3, 4, 5, 6]
  print $ harm [2, 4, 6, 8]
  print $ harm [2]
  print $ harm []

3d version does not folding all items but drops all 0's until find first non zero which means that non-harmonic series are found:

neighOp op [] = []
neighOp op l@(hd:xs) = zipWith op l xs

harm [] = False
harm [x] = False
harm ns = case dropWhile (==0) $ neighOp (-) $ neighOp (-) ns of
  [] -> True
  _ -> False


main = do
  print $ harm [1, 2, 3, 4, 5, 6, 9]
  print $ harm [1, 2, 3, 4, 5, 6]
  print $ harm [2, 4, 6, 8]
  print $ harm [2]
  print $ harm []

Case will be lazy so calculations happens until first non-zero item in 2nd difference.

Комментариев нет:

Отправить комментарий

Thanks for your posting!