Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions knapsack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""One-liner knapsack problem solution"""

from collections import namedtuple
import csv
from itertools import accumulate
from itertools import takewhile
from itertools import tee


thing = namedtuple('thing', 'item weight value')
knapsack_capacity = 400

# data preparation
with open('knapsack_items_data', newline='') as data_file:
items = [thing(x[0], int(x[1]), int(x[2]))
for x in csv.reader(data_file, delimiter=',')]

# First approach
# Can be shorter in case of prepared ordered things list
things = ([y.item for y in sorted(
items, key=lambda x: x.value / x.weight, reverse=True)[
:len([x for x in takewhile(
lambda x: x < knapsack_capacity,
accumulate(
[item.weight for item in sorted(
items, key=lambda k: k.value / k.weight,
reverse=True)]))])]])

print(things)

# Second approach
things = [r[1].item for r in [
zip(takewhile(lambda y: y < knapsack_capacity,
accumulate(item.weight for item in x[0])), x[1])
for x in [tee(sorted(items, key=lambda k: k.value / k.weight,
reverse=True), 2)]][0]]

print(things)
22 changes: 22 additions & 0 deletions knapsack_items_data
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
map,9,150
compass,13,35
water,153,200
sandwich,50,160
glucose,15,60
tin,68,45
banana,27,60
apple,39,40
cheese,23,30
beer,52,10
suntan cream,11,70
camera,32,30
T-shirt,24,15
trousers,48,10
umbrella,73,40
waterproof trousers,42,70
waterproof overclothes,43,75
note-case,22,80
sunglasses,7,20
towel,18,12
socks,4,50
book,30,10