-- メモ版(memocc) type Amount = Integer type Coin = Integer type Count = Integer memocc :: Amount -> [Coin] -> Table -> (Count, Table) memocc 0 _ tbl = (1,tbl) -- 1: memocc _ [] tbl = (0,tbl) -- 2: memocc a ccs@(c:cs) tbl -- 3: | a < 0 = (0,tbl) -- 4: | otherwise = case lookupTable (a,ccs) tbl of -- 5: 表を索く (v:_) -> (v,tbl) -- 6: 表に登録済の場合 [] -> let -- 7: 表に未登録の場合 (cnt1,tbl1) = memocc (a-c) ccs tbl -- 8: 左の枝 (cnt2,tbl2) = memocc a cs tbl1 -- 9: 右の枝 cnt3 = cnt1 + cnt2 -- 10: 左右の結果の合成 tbl3 = insertTable (a,ccs) cnt3 tbl2 -- 11: 表に新たなエントリ追加 in (cnt3,tbl3) -- 12: 返り値 evalMemoCC :: Amount -> [Coin] -> Count evalMemoCC amount coins = fst (memocc amount coins emptyTable) -- Table の定義 type Table = [(Key,Value)] type Key = (Amount,[Coin]) type Value = Count emptyTable :: Table emptyTable = [] lookupTable :: Key -> Table -> [Value] -- 表を索く lookupTable key [] = [] lookupTable key ((k,v):tbl) | key > k = [] | key == k = [v] | key < k = lookupTable key tbl insertTable :: Key -> Value -> Table -> Table -- 表にエントリを追加する insertTable k v tbl = case break ((k >) . fst) tbl of (xs,ys) -> xs ++ (k,v):ys