Paste: Knappsack

Author: Sam
Mode: factor
Date: Sat, 3 Apr 2010 16:57:00
Plain Text |
USING: accessors arrays fry io kernel locals make math
math.order math.parser math.ranges namespaces sequences sorting ;
IN: rosetta.knappsack

TUPLE: item name weight value ;

CONSTANT: items {
        T{ item f "map" 9 150 }
        T{ item f "compass" 13 35 }
        T{ item f "water" 153 200 }
        T{ item f "sandwich" 50 160 }
        T{ item f "glucose" 15 60 }
        T{ item f "tin" 68 45 }
        T{ item f "banana" 27 60 }
        T{ item f "apple" 39 40 }
        T{ item f "cheese" 23 30 }
        T{ item f "beer" 52 10 }
        T{ item f "suntan cream" 11 70 }
        T{ item f "camera" 32 30 }
        T{ item f "t-shirt" 24 15 }
        T{ item f "trousers" 48 10 }
        T{ item f "umbrella" 73 40 }
        T{ item f "waterproof trousers" 42 70 }
        T{ item f "waterproof overclothes" 43 75 }
        T{ item f "note-case" 22 80 }
        T{ item f "sunglasses" 7 20 }
        T{ item f "towel" 18 12 }
        T{ item f "socks" 4 50 }
        T{ item f "book" 30 10 }
    }

CONSTANT: limit 400

: total-weight ( seq -- n )
    [ weight>> ] map sum ;

: total-value ( seq -- n )
    [ value>> ] map sum ;

SYMBOL: best-knappsack
SYMBOL: best-value

: check-knappsack ( sack -- )
    dup total-value dup best-value get >
    [ best-value set best-knappsack set ] [ 2drop ] if ;

: add-to-knappsack ( seq sack -- )
    dup total-weight limit > [
        2drop
    ] [
        over empty?
        [
            check-knappsack drop
        ] [
            [ unclip ] dip [ swap suffix ] [ nip ] 3bi
            [ add-to-knappsack ] 2bi@
        ] if
    ] if ;


: solve-knappsack ( -- items value )
    0 best-value set items { } add-to-knappsack
    best-knappsack get [ name>> ] map best-value get ;

: main ( -- )
    solve-knappsack
    "Total value: " write number>string print
    "Items packed: " print
    natural-sort
    [ "   " write print ] each ;

New Annotation

Summary:
Author:
Mode:
Body: