I have converted some code in Python into its Haskell equivalent.
Python implementation:
def final_codes( bit_lengths, next_code ): tree_code = [] for i in range(len(bit_lengths)): tree_code.append( next_code[ bit_lengths[i] ] ) next_code[bit_lengths[i]] += 1 return tree_code #Inputs: bit_lengths = [ 3, 3, 3, 3, 3, 2, 4, 4 ] next_code = [0,0,0,2,14] print final_codes( bit_lengths, next_code ) [2, 3, 4, 5, 6, 0, 14, 15]
Haskell implementation:
replaceNth :: (Eq a, Num a) => a -> a1 -> [a1] -> [a1]
replaceNth n newVal (x:xs) # Picked this function from somewhere on stackoverflow.
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
final_codes' :: (Eq a, Num a, Num a1) => [a1] -> [Int] -> [a1] -> a -> [a1]
final_codes' lst bit_lngths next_cd 0 = lst
final_codes' lst bit_lngths next_cd n = final_codes' new_lst bit_lngths new_next_code (n-1)
where tlen = bit_lngths !! (length lst)
new_lst = (next_cd !! tlen) : lst
new_next_code = replaceNth tlen ((next_cd !! tlen) + 1) next_cd -- INEFFICIENT!
final_codes :: Num a => [Int] -> [a] -> [a]
final_codes bit_lengths next_code = reverse $ final_codes' [] bit_lengths next_code (length bit_lengths)
In the last where statement in final_codes'
I create a new_next_code
list by incrementing the value at position tlen
by 1. This makes the algorithm \$O(N^2)\$ in comparison to the \$O(N)\$ implementation in Python.
This approach works but it feels a bit contrived. Any suggestions on how I could improve this code and its performance?
Note: I'd like to avoid using the lens
library for now (I'm still a novice). I found this Stack Overflow link on replacing a single element in a list; but most approaches are \$O(N)\$. I haven't yet dug into the versions that use lens
.