【发布时间】:2021-11-16 22:17:01
【问题描述】:
我正在尝试将以下玩具动态编程问题转换为 Elixir,但考虑到 Elixir 没有提前返回,我很难了解如何做到这一点。
它应该从“数字”返回一个有效的组合,总和为“targetSum”
const howSum = (targetSum, numbers) => {
if (targetSum === 0) return [];
if (targetSum < 0) return null;
for (let num of numbers) {
const remainder = targetSum - num;
const remainderResult = howSum(remainder, numbers);
if (remainderResult !== null) {
return [...remainderResult, num];
}
}
return null;
}
console.log(howSum(7, [2, 3])) // [3,2,2]
我可以低于 Elixir 版本以使用列表理解记录所有可能的解决方案,但我怎样才能让函数返回找到的第一个解决方案并在该点返回/停止?
defmodule HowSum do
@doc """
Can you make target_sum from numbers list
You can use individual numbers as many times as you like
"""
def sum(0, _numbers, _), do: []
def sum(target_sum, _numbers, _) when target_sum < 0, do: nil
def sum(target_sum, numbers, path) do
for number <- numbers do
remainder = target_sum - number
result = sum(remainder, numbers, path ++ [number])
if result == [] do
IO.inspect(path ++ [number])
end
end
end
end
更新
这是我的解决方案,它看起来并不惯用,但可以使用代理 :-)
defmodule HowSum do
def cache do
Agent.start_link(fn -> nil end, name: :solution)
end
@doc """
Can you make target_sum from numbers list
You can use individual numbers as many times as you like
"""
def sum(0, _numbers, _), do: []
def sum(target_sum, _numbers, _) when target_sum < 0, do: nil
def sum(target_sum, numbers, path) do
solution = Agent.get(:solution, & &1)
if !solution do
for number <- numbers do
remainder = target_sum - number
result = sum(remainder, numbers, path ++ [number])
if result == [] do
Agent.update(:solution, &(&1 = path ++ [number]))
end
end
end
Agent.get(:solution, & &1)
end
end
【问题讨论】:
-
我认为Enum.find_value/3 可能会有所帮助
标签: elixir dynamic-programming