[Prev][Next][Index][Thread]
Re: Quick permutations, another entry
> This runs in under 0.5 seconds on a 450Mhz, Pentium III. If anyone
> wants to improve the code, please go ahead.
Yours certainly runs quickly! Another entry comes from jt (jan) that
also runs in less than 0.5 seconds and entirely side-steps the
memory-management problem by only retaining the current permutation
(which it shares out to the world via a function):
define constant $permuted-vector-size = 8;
define variable *permutation* = make(<vector>, size: 8);
define class <position> (<object>)
slot available? :: <boolean> = #t, init-keyword: available?:;
slot value, init-keyword: value:;
end class;
define constant <permuted-vector> = limited(<vector>, of: <position>);
define variable *taken* :: <permuted-vector> =
make(<permuted-vector>, size: 8, fill: make(<position>));
define macro with-available-position
{ with-available-position(?position:variable = ?x:expression) ?:body
end
} => {
if(?x.available?)
?x.available? := #f;
let ?position = ?x.value;
?body;
?x.available? := #t;
end if;
}
end macro;
define method permute(permuted-fill-pointer :: <integer>,
f :: <function>)
if (permuted-fill-pointer == $permuted-vector-size) // permutation
complete
f(*permutation*);
else
for(pos from 0 below $permuted-vector-size)
with-available-position(item = *taken*[pos])
*permutation*[permuted-fill-pointer] := item;
permute(permuted-fill-pointer + 1, f);
end;
end for;
end if;
end method permute;
define method init-taken()
for(x from 1 to 8)
*taken*[x - 1] := make(<position>, value: x);
end;
end method;
define method permute-example()
init-taken();
let (seconds, milliseconds) = timing ()
permute(0, curry(format-out, "%=\n"));
end;
format-out("%d seconds %d milliseconds\n", seconds, milliseconds);
end method;
Sent via Deja.com
http://www.deja.com/
Follow-Ups:
References: