langs a-z

This commit is contained in:
Ingy döt Net 2013-04-10 22:43:41 -07:00
parent db842d013d
commit d066446780
11389 changed files with 98361 additions and 1020 deletions

View file

@ -0,0 +1,41 @@
let items = [
"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;
]
let comb =
List.fold_left (fun acc x -> let acc2 = List.rev_map (fun li -> x::li) acc in
List.rev_append acc acc2) [[]]
let score =
List.fold_left (fun (w_tot,v_tot) (_,w,v) -> (w + w_tot, v + v_tot)) (0,0)
let () =
let combs = comb items in
let vals = List.rev_map (fun this -> (score this, this)) combs in
let poss = List.filter (fun ((w,_), _) -> w <= 400) vals in
let _, res = List.fold_left (fun (((_,s1),_) as v1) (((_,s2),_) as v2) ->
if s2 > s1 then v2 else v1)
(List.hd poss) (List.tl poss) in
List.iter (fun (name,_,_) -> print_endline name) res;
;;

View file

@ -0,0 +1,64 @@
declare
%% maps items to pairs of Weight(hectogram) and Value
Problem = knapsack('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
)
%% item -> Weight
Weights = {Record.map Problem fun {$ X} X.1 end}
%% item -> Value
Values = {Record.map Problem fun {$ X} X.2 end}
proc {Knapsack Solution}
%% a solution maps items to finite domain variables
%% with the domain {0,1}
Solution = {Record.map Problem fun {$ _} {FD.int 0#1} end}
%% no more than 400 hectograms
{FD.sumC Weights Solution '=<:' 400}
%% search through valid solutions
{FD.distribute naive Solution}
end
proc {PropagateLargerValue Old New}
%% propagate that new solutions must yield a higher value
%% than previously found solutions (essential for performance)
{FD.sumC Values New '>:' {Value Old}}
end
fun {Value Candidate}
{Record.foldL {Record.zip Candidate Values Number.'*'} Number.'+' 0}
end
fun {Weight Candidate}
{Record.foldL {Record.zip Candidate Weights Number.'*'} Number.'+' 0}
end
[Best] = {SearchBest Knapsack PropagateLargerValue}
in
{System.showInfo "Items: "}
{ForAll
{Record.arity {Record.filter Best fun {$ T} T == 1 end}}
System.showInfo}
{System.printInfo "\n"}
{System.showInfo "total value: "#{Value Best}}
{System.showInfo "total weight: "#{Weight Best}}

View file

@ -0,0 +1,45 @@
my class KnapsackItem { has $.name; has $.weight; has $.unit; }
multi sub pokem ([], $, $v = 0) { $v }
multi sub pokem ([$, *@], 0, $v = 0) { $v }
multi sub pokem ([$i, *@rest], $w, $v = 0) {
my $key = "{+@rest} $w $v";
(state %cache){$key} or do {
my @skip = pokem @rest, $w, $v;
if $w >= $i.weight { # next one fits
my @put = pokem @rest, $w - $i.weight, $v + $i.unit;
return (%cache{$key} = @put, $i.name).list if @put[0] > @skip[0];
}
return (%cache{$key} = @skip).list;
}
}
my $MAX_WEIGHT = 400;
my @table = map -> $name, $weight, $unit {
KnapsackItem.new: :$name, :$weight, :$unit;
},
'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;
my ($value, @result) = pokem @table, $MAX_WEIGHT;
say "Value = $value\nTourist put in the bag:\n " ~ @result;

View file

@ -0,0 +1,116 @@
Structure item
name.s
weight.i ;units are dekagrams (dag)
Value.i
EndStructure
Structure memo
Value.i
List picked.i()
EndStructure
Global itemCount = 0 ;this will be increased as needed to match count
Global Dim items.item(itemCount)
Procedure addItem(name.s, weight, Value)
If itemCount >= ArraySize(items())
Redim items.item(itemCount + 10)
EndIf
With items(itemCount)
\name = name
\weight = weight
\Value = Value
EndWith
itemCount + 1
EndProcedure
;build item list
addItem("map", 9, 150)
addItem("compass", 13, 35)
addItem("water", 153, 200)
addItem("sandwich", 50, 160)
addItem("glucose", 15, 60)
addItem("tin", 68, 45)
addItem("banana", 27, 60)
addItem("apple", 39, 40)
addItem("cheese", 23, 30)
addItem("beer", 52, 10)
addItem("suntan cream", 11, 70)
addItem("camera", 32, 30)
addItem("t-shirt", 24, 15)
addItem("trousers", 48, 10)
addItem("umbrella", 73, 40)
addItem("waterproof trousers", 42, 70)
addItem("waterproof overclothes", 43, 75)
addItem("note-case", 22, 80)
addItem("sunglasses", 7, 20)
addItem("towel", 18, 12)
addItem("socks", 4, 50)
addItem("book", 30, 10)
Procedure knapsackSolveFast(Array item.item(1), i, aw, Map m.memo())
Protected.memo without_i, with_i, result, *tmp, memoIndex.s = Hex((i << 16) + aw, #PB_Long)
If FindMapElement(m(), memoIndex)
ProcedureReturn @m()
Else
If i = 0
If item(0)\weight <= aw
;item fits
m(memoIndex)\Value = item(0)\Value ;memo this item's value
AddElement(m()\picked())
m()\picked() = 0 ;memo item's index also
Else
;item doesn't fit, memo a zero Value
m(memoIndex)\Value = 0
EndIf
ProcedureReturn @m()
EndIf
;test if a greater value results with or without item included
*tmp = knapsackSolveFast(item(), i - 1, aw, m()) ;find value without this item
CopyStructure(*tmp, @without_i, memo)
If item(i)\weight > aw
;item weighs too much, memo without including this item
m(memoIndex) = without_i
ProcedureReturn @m()
Else
*tmp = knapsackSolveFast(item(), i - 1, aw - item(i)\weight, m()) ;find value when item is included
CopyStructure(*tmp, @with_i, memo)
with_i\Value + item(i)\Value
AddElement(with_i\picked())
with_i\picked() = i ;add item to with's picked list
EndIf
;set the result to the larger value
If with_i\Value > without_i\Value
result = with_i
Else
result = without_i
EndIf
m(memoIndex) = result ;memo the result
ProcedureReturn @m()
EndIf
EndProcedure
Procedure.s knapsackSolve(Array item.item(1), i, aw)
Protected *result.memo, output.s, totalWeight
NewMap m.memo()
*result = knapsackSolveFast(item(), i, aw, m())
output = "Knapsack:" + #CRLF$
ForEach *result\picked()
output + LSet(item(*result\picked())\name, 24) + RSet(Str(item(*result\picked())\weight), 5) + RSet(Str(item(*result\picked())\Value), 5) + #CRLF$
totalWeight + item(*result\picked())\weight
Next
output + LSet("TOTALS:", 24) + RSet(Str(totalWeight), 5) + RSet(Str(*result\Value), 5)
ProcedureReturn output
EndProcedure
If OpenConsole()
#maxWeight = 400
Define *result.memo
PrintN(knapsackSolve(items(), itemCount - 1, #maxWeight))
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf

View file

@ -0,0 +1,44 @@
#import std
#import nat
#import flo
#import lin
#import nat
items = # name: (weight,value)
<
'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)>
system =
linear_system$[
binaries: ~&nS,
lower_bounds: {'(slack)': 0.}!,
costs: * ^|/~& negative+ float@r,
equations: ~&iNC\400.+ :/(1.,'(slack)')+ * ^|rlX/~& float@l]
#show+
main = ~&tnS solution system items

View file

@ -0,0 +1,57 @@
include c:\cxpl\codes; \include 'code' declarations
int Item, Items, Weights, Values,
BestItems, BestValues,
I, W, V, N;
def Tab=9;
def Name, Weight, Value;
[Item:= [["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]];
BestValues:= 0;
for Items:= 0 to 1<<22-1 do \for all possible combinations of Items...
[I:= Items; W:= 0; V:= 0; N:= 0;
while I do \add weights and values for each item (bit in I)
[if I&1 then
[W:= W + Item(N,Weight); V:= V + Item(N,Value)];
I:= I>>1; N:= N+1;
];
if V>BestValues & W<=400 then \save best combination found so far
[BestValues:= V; BestItems:= Items];
];
I:= BestItems; W:= 0; V:= 0; N:= 0; \show best combination of items
while I do
[if I&1 then
[Text(0, " "); Text(0, Item(N,Name)); ChOut(0, Tab);
IntOut(0, Item(N,Weight)); ChOut(0, Tab);
IntOut(0, Item(N,Value)); CrLf(0);
W:= W + Item(N,Weight);
V:= V + Item(N,Value);
];
I:= I>>1; N:= N+1;
];
Text(0, "Totals: ");
IntOut(0, W); ChOut(0, Tab);
IntOut(0, V); CrLf(0);
]