Opi napisał(a)
mgr.Dobrowolski napisał(a)
Czyli w sumie, kolejne rozwiazanie konkursu
Rozwiązanie będzie jak to przepiszesz do Delphi, a na razie jest to tylko schemat.
Jest to sprawdzony kod, kod PARI/GP.
Ale dobra, przepisałem na pascal (Free Pascal), zmierzyłem czas znalezienia wszystkich C(49,6) kombinacji (oczywiście bez wyświetlania).
uses sysutils;
function C(n,k:integer):integer;
var i:integer;
begin
//if 2*k>n then k:=n-k;
result:=1;
for i:=1 to k do begin
result:=result*n div i;
n:=n-1;
end
end;
procedure BogdanS(l,n,k:integer); // kosmetyczne poprawki
var zilu, liczba, poprzednia, s:integer;
begin
dec(n); dec(k);
zilu:=n;
while k>=0 do begin
s:=0; poprzednia:=0;
while s<l do begin
poprzednia:=s;
s:=s + C(n,k);
dec(n);
end;
liczba:=zilu-n;
//write(liczba,#32);
l:=l-poprzednia;
n:=zilu-liczba;
dec(k)
end;
end;
procedure BogdansX(l,b,n,k:integer); // pozbyłem się wołania funkcji C(n,k)
var zilu, liczba, poprzednia, s:integer;
begin
dec(n); dec(k);
zilu:=n;
while k>=0 do begin
s:=0; poprzednia:=0;
while s<l do begin
poprzednia:=s;
s:=s + b;
if n>0 then b:=b*(n-k) div n
else b:=1;
dec(n);
end;
liczba:=zilu-n;
//write(liczba,#32);
l:=l-poprzednia;
n:=zilu-liczba;
if n-k+1>0 then b:=b*k div (n-k+1)
else b:=1;
dec(k)
end;
end;
procedure xitami(z,b,n,k: integer);
var c:integer;
begin
dec(n); dec(k);
c:=1;
while k>=0 do
if z<b then begin
//write(c,#32);
inc(c);
if n>0 then
b:=b*k div n;
dec(n); dec(k);
end else begin
inc(c);
z:=z-b;
b:=b*(n-k) div n;
dec(n)
end
end;
procedure f(c,z,b,n,k:integer); // wersja rekurencyjna
begin
if z<b then begin
//write(c,#32);
if n>0 then
f(c+1, z, b*k div n, n-1, k-1)
end else
if n>0 then
f(c+1, z-b, b*(n-k) div n, n-1, k )
end;
var n,k,z,b,nk:integer; czas:double;
begin
n:=49; k:=6;
b:=C(n-1, k-1);
nk:=C(n,k);
writeln(n,' ',k,' ',nk);
writeln('--------------- sekund');
czas:=time;
for z:=0 to nk-1 do
f(1,z,b, n-1, k-1);
writeln(' rekurencja ',(time-czas)*24*60*60:8:2);
czas:=time;
for z:=1 to nk do
bogdansx(z, b, n, k);
writeln(' BogdansX ',(time-czas)*24*60*60:8:2);
czas:=time;
for z:=1 to nk do
bogdans(z, n, k);
writeln(' Bogdans ',(time-czas)*24*60*60:8:2);
czas:=time;
for z:=0 to nk-1 do
xitami(z, b, n, k);
writeln(' Xitami ',(time-czas)*24*60*60:8:2);
writeln;
end.
Wyniki to:
Running "c:\download\lotto1.exe "
49 6 13983816
--------------- sekund
rekurencja 43.96
BogdansX 38.81
Bogdans 88.57
Xitami 31.04</b></b>