35 lines
1.2 KiB
Plaintext
35 lines
1.2 KiB
Plaintext
defmodule KnapsackProblem do
|
|
def price_per_weight( items ), do: (for {name, weight, price} <-items, do: {name, weight, price / weight} )
|
|
|
|
def select( max_weight, items ) do
|
|
{_remains, selected_items} = List.foldr( List.keysort(items, 2), {max_weight, []}, &select_until/2 )
|
|
selected_items
|
|
end
|
|
|
|
def task( max_weight, items ) do
|
|
IO.puts "The robber takes the following to maximize the value"
|
|
for {name, weight} <- select( max_weight, price_per_weight(items) ), do: :io.fwrite("~.2f of ~s~n", [weight, name])
|
|
end
|
|
|
|
defp select_until( {name, weight, _price}, {remains, acc} ) when remains > 0 do
|
|
selected_weight = select_until_weight( weight, remains )
|
|
{remains - selected_weight, [{name, selected_weight} | acc]}
|
|
end
|
|
defp select_until( _item, acc ), do: acc
|
|
|
|
defp select_until_weight( weight, remains ) when weight < remains, do: weight
|
|
defp select_until_weight( _weight, remains ), do: remains
|
|
end
|
|
|
|
items = [ {"beef", 3.8, 36},
|
|
{"pork", 5.4, 43},
|
|
{"ham", 3.6, 90},
|
|
{"greaves", 2.4, 45},
|
|
{"flitch", 4.0, 30},
|
|
{"brawn", 2.5, 56},
|
|
{"welt", 3.7, 67},
|
|
{"salami", 3.0, 95},
|
|
{"sausage", 5.9, 98} ]
|
|
|
|
KnapsackProblem.task( 15, items )
|