dynamic programming - Counting change in Haskell -


i came across following solution dp problem of counting change:

count' :: int -> [int] -> int count' cents coins = aux coins !! cents   aux = foldr addcoin (1:repeat 0)           addcoin c oldlist = newlist                   newlist = (take c oldlist) ++ zipwith (+) newlist (drop c oldlist) 

it ran faster naive top-down recursive solution, , i'm still trying understand it.

i given list of coins, aux computes every solution positive integers. solution amount index list @ position.

i'm less clear on addcoin, though. somehow uses value of each coin draw elements list of coins? i'm struggling find intuitive meaning it.

the fold in aux ties brain in knots. why 1:repeat 0 initial value? represent?

it's direct translation of imperative dp algorithm problem, looks (in python):

def count(cents, coins):     solutions = [1] + [0]*cents # [1, 0, 0, 0, ... 0]     coin in coins:         in range(coin, cents + 1):             solutions[i] += solutions[i - coin]     return solutions[cents] 

in particular, addcoin coin solutions corresponds to

for in range(coin, cents + 1):     solutions[i] += solutions[i - coin] 

except addcoin returns modified list instead of mutating old one. haskell version, result should have unchanged section @ beginning until coin-th element, , after must implement solutions[i] += solutions[i - coin].

we realize unchanged part take c oldlist , modified part zipwith (+) newlist (drop c oldlist). in modified part add i-th elements of old list , i - coin-th elements of resulting list. shifting of indices implicit in drop , take operations.

a simpler, classic example kind of shifting , recursive definition fibonacci numbers:

fibs = 0 : 1 : zipwith (+) fibs (tail fibs) 

we write imperatively as

def fibs(limit):     res = [0, 1] + [0]*(limit - 2)     in range(2, limit):         res[i] = res[i - 2] + res[i - 1]     return res 

turning coin change, foldr addcoin (1:repeat 0) corresponds initialization of solutions , loop on coins, change initial list infinite instead of finite (because laziness lets that).


Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -