我对 Haskell 很陌生,并且对改进我对“给定金额(以美分)为单位的问题的解决方案很感兴趣,请确定在给定面额列表的情况下进行更改的所有方法”。
change :: Int -> [Int] -> [[Int]]
change amt [] = [[]]
change amt [d] = [replicate (quot amt d) d]
change amt (d:denoms) =
if d <= amt then
reverse [0..(quot amt d)] >>= \x ->
[(replicate x d) ++ c | c <- (change (amt - (x*d)) denoms)]
else
change amt denoms
changeUS amt = change amt [25, 10, 5, 1]
-- *Main> changeUS 29
-- [[25,1,1,1,1],[10,10,5,1,1,1,1],[10,10,1,1,1,1,1,1,1,1,1],[10,5,5,5,1,1,1,1],[10,5,5,1,1,1,1,1,1,1,1,1],[10,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[5,5,5,5,5,1,1,1,1],[5,5,5,5,1,1,1,1,1,1,1,1,1],[5,5,5,1,1,1,1,1,1,1,1,1,11,1,1,1],[5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]
此解决方案的一个问题是它假设最低面额为 1。否则,change amt [d]
情况将不正确。我可以添加一个if/then
以确保在这种情况下amt
可以被整除d
,但它开始变得有点冗长,我认为这种情况在更好的解决方案中甚至不是必需的。