Если вы не хотите сказать, что пустые списки на входе всегда плохие (даже n = 0 со списком []), я бы рекомендовал возвращать что-то другое для пустого списка, основываясь на том, достигли ли вы 0 наконец (все было вычтено) или нет, затем выполните рекурсию при получении любого непустого списка, а не специального списка из одного элемента.
Что касается третьего шага, вам нужно проверить каждые возможное положительное целое число, кратное первому элементу вашего списка ввода, пока они не превысят n, а не только первый и последний.Первое полученное значение, отличное от None, достаточно хорошо, поэтому вы просто добавляете множитель (не кратный) к списку возврата.Если все дает вам Nones, вы возвращаете None.
Я не знаю SML, но вот как я это сделаю в Haskell:
import Data.Maybe (isJust, listToMaybe)
-- Find linear combinations of positive integers
solve :: Integer -> [Integer] -> Maybe [Integer]
-- If we've made it to the end with zero left, good!
solve 0 [] = Just []
-- Otherwise, this way isn't the way to go.
solve _ [] = Nothing
-- If one of the elements of the input list is zero, just multiply that element by one.
solve n (0:xs) = case solve n xs of
Nothing -> Nothing
Just ys -> Just (1:ys)
solve n (x:xs) = listToMaybe -- take first solution if it exists
. map (\ (m, Just ys) -> m:ys) -- put multiplier at front of list
. filter (isJust . snd) -- remove nonsolutions
. zip [1 ..] -- tuple in the multiplier
. map (\ m -> solve (n - m) xs) -- use each multiple
$ [x, x + x .. n] -- the multiples of x up to n
Здесьон решает 11
с [1, 2]
и 1
с [1, 2]
.