16. august 2004 - 20:24Der er
47 kommentarer og 1 løsning
skal ikke medtages hvis ikke heltal
Hej
Jeg har en funktion der skal udregne såkaldte perfekte tal. Jeg har så lavet dette: ----------------------------------- var a : array[0..2500] of real; i,x,y : integer; begin
a[0] := StrToInt(Edit1.Text); x := 1; y := StrToInt(Edit1.Text); for i := StrToInt(FloatToStr(a[0])) downto 0 do begin a[x] := StrToInt(FloatToStr(a[0]/y)); x := x+1; y := y-1; end; i := i+1; ----------------------------------
Nu til spørgsmålet, jeg vil gerne have det sådan at hvis det den regner ud er et decimaltal, så skal der enten skrives 0 i a[x] eller også skal den slet ikke medregnes. Men sådan som det er nu, så går den amok når den kommer til et decimaltal. Jeg skal altså kun bruge heltal, for at kunne regne de såkaldte perfekte tal ud. Nogen der kan hjælpe mig?
Et perfekt tal er f.eks. 6, fordi alt det 6 kan divideres med sammenlagt giver 6. F.eks. så er 28 også et perfekt tal (28 = 1+2+4+7+14)
En simpel, ikke synderligt effektiv funktion til perfekte tal er:
function perfekttal(tal: integer): boolean; var i,sum: integer; begin sum:=0; for i:=1 to tal-1 do if (tal mod i)=0 then sum:=sum+i; perfekttal:=(tal=sum); end;
var na, i, sum : integer; a : array [0..10000] of integer;
begin na := 0; for i := 1 to (n div 2 + 1) do begin if (n mod i) = 0 then begin a[na] := i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfect := (sum = n); end;
function IsPerfectOpt(n : integer) : boolean;
var sqrtn, na, i, sum : integer; a : array [0..10000] of integer;
begin sqrtn := trunc(sqrt(n)); na := 0; a[na] := 1; inc(na); for i := 2 to sqrtn do begin if (n mod i) = 0 then begin a[na] := i; inc(na); a[na] := n div i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfectOpt := (sum = n); end;
var i, t1, t2, t3 : integer;
begin t1 := GetTickCount; for i := 1 to 10000 do begin if IsPerfect(i) then begin writeln(i); end; end; t2 := GetTickCount; for i := 1 to 10000 do begin if IsPerfectOpt(i) then begin writeln(i); end; end; t3 := GetTickCount; writeln(t2-t1,' ',t3-t2); end.
Jeg mener: det giver ingen mening at sammenligne tid på to vidt forskellige algoritmer. Det er forkert kun at gå op til kvadratroden, men ok at gå op til halvdelen af tallet. Den men halvdelen bruger man også til primtalstest, selv om det ikke sparer så meget - derfor min hurtige reaktion...
Sådan en PC har jeg også haft en gang ;) Nej, spøg til side, men det går hurtigt galt når tallene bliver større. Kender du til teorien for perfekte tal? Og hvorfor er det lige det du får en mandag aften til gå med?
Har lige stoppet processen, min computer kunne slet ikke klare det, den må prøve engang jeg ikke er hjemme.
Det med perfekte tal er noget jeg læste i Illustreret Videnskab, så ville jeg da bare lige se om jeg kunne "finde" nogle flere end dem de har nævnt.
Grunden til at jeg får en mandag til at gå med det er at jeg keder mig SINDSYGT meget. Jeg ved slet ikke hvad jeg skal lave når jeg er hjemme. Så jeg får tiden til at gå med at lave unyttige ting. -Men hvis nogen har nogle idéer til hvad man kan lave, så er foreslag da velkomne.
Ked dig ikke. Søg på google - sjov læsning med gamle grækere og arabare. En liste over 41 kendte: http://amicable.homepage.dk/perfect.htm (jeg kender ham, der har siden...)
Ja, det tror jeg ikke vores programmer kunne have fundet ;) 6 er et perfekt tal, og gud siges at have skabt jorden på 6 dage 28 er et perfekt tal, og månen er 28 dage om en rundtur 496 er et perfekt tal, og antal dage på et år er ... eh ... ca. 365 dage ... - øv, det duede ikke.
I meget gamle dage (mis)brugte Jan, fra bemeldte hjemmeside, universitetets computere til en masse beregninger af denne karakter. Umiddelbart nytteløst, men meget sjovere end at se reklamer på TV2. Det var også lang tid før nogen synes det var nødvendigt med mere end een TV-kanal.
Hvis man kan stole på det bit mønster der outlines på den side der linkes til i det link Erik gav, så kan man optimere rigtigt meget !
program perfect;
{$APPTYPE CONSOLE}
uses Windows, SysUtils;
function IsPerfect(n : integer) : boolean;
var na, i, sum : integer; a : array [0..10000] of integer;
begin na := 0; for i := 1 to (n div 2 + 1) do begin if (n mod i) = 0 then begin a[na] := i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfect := (sum = n); end;
function IsPerfectOpt(n : integer) : boolean;
var sqrtn, na, i, sum : integer; a : array [0..10000] of integer;
begin sqrtn := trunc(sqrt(n)); na := 0; a[na] := 1; inc(na); for i := 2 to sqrtn do begin if (n mod i) = 0 then begin a[na] := i; inc(na); a[na] := n div i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfectOpt := (sum = n); end;
var bitfit : array [1..15] of integer;
function IsPerfectMoreOpt(n : integer) : boolean;
var i : integer; candidate : boolean;
begin candidate := false; for i := 1 to 15 do begin if bitfit[i] = n then candidate := true; end; if candidate then IsPerfectMoreOpt := IsPerfectOpt(n) else IsPerfectMoreOpt := false; end;
var i, t1, t2, t3, t4 : integer;
begin bitfit[1] := 1; for i := 2 to 15 do bitfit[i] := (bitfit[i-1] shl 1) + 1; for i := 1 to 15 do bitfit[i] := bitfit[i] shl (i - 1); t1 := GetTickCount; for i := 1 to 10000 do begin if IsPerfect(i) then begin writeln(i); end; end; t2 := GetTickCount; for i := 1 to 10000 do begin if IsPerfectOpt(i) then begin writeln(i); end; end; t3 := GetTickCount; for i := 1 to 10000 do begin if IsPerfectMoreOpt(i) then begin writeln(i); end; end; t4 := GetTickCount; writeln(t2-t1,' ',t3-t2,' ',t4-t3); end.
var na, i, sum : integer; a : array [0..10000] of integer;
begin na := 0; for i := 1 to (n div 2 + 1) do begin if (n mod i) = 0 then begin a[na] := i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfect := (sum = n); end;
function IsPerfectOpt(n : integer) : boolean;
var sqrtn, na, i, sum : integer; a : array [0..10000] of integer;
begin sqrtn := trunc(sqrt(n)); na := 0; a[na] := 1; inc(na); for i := 2 to sqrtn do begin if (n mod i) = 0 then begin a[na] := i; inc(na); a[na] := n div i; inc(na); end; end; sum := 0; for i := 0 to (na - 1) do begin sum := sum + a[i]; end; IsPerfectOpt := (sum = n); end;
var bitfit : array [1..15] of integer;
function IsPerfectMoreOpt(n : integer) : boolean;
var i : integer; candidate : boolean;
begin candidate := false; for i := 1 to 15 do begin if bitfit[i] = n then candidate := true; end; if candidate then IsPerfectMoreOpt := IsPerfectOpt(n) else IsPerfectMoreOpt := false; end;
var i, t1, t2, t3, t4 : integer;
begin bitfit[1] := 1; for i := 2 to 15 do bitfit[i] := (bitfit[i-1] shl 1) + 1; for i := 1 to 15 do bitfit[i] := bitfit[i] shl (i - 1); t1 := GetTickCount; (* for i := 1 to 10000 do begin if IsPerfect(i) then begin writeln(i); end; end; t2 := GetTickCount; for i := 1 to 10000 do begin if IsPerfectOpt(i) then begin writeln(i); end; end; t3 := GetTickCount; for i := 1 to 10000 do begin if IsPerfectMoreOpt(i) then begin writeln(i); end; end; t4 := GetTickCount; writeln(t2-t1,' ',t3-t2,' ',t4-t3); *) for i := 1 to 100000000 do begin if IsPerfectMoreOpt(i) then begin writeln(i); end; end; end.
Ja det tror jeg. Jeg kiggede nemlig nogle gamle indlæg igennem, hvor der også stod noget om bigint.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.