Egyensúlyszámok
Egy természetes számot egyensúlyszámnak (Balance number) nevezünk, ha az összes előtte lévő természetes szám összege egyenlő, az őt követő valahány természetes szám összegével.
A 6 például
egy egyensúlyszám, hiszen teljesíti a fenti definíciót, ugyanis: 1+2+3+4+5 =
7+8. További néhány egyensúlyszám: 6,
35, 204, 1189, 6930, 40391. Írjunk programot, mely a gép adta lehetőségeket
kihasználva a lehető legnagyobb értékig meghatározza az összes egyensúlyszámot.
A többször módosított, egyre magasabb
értékekre is elfogadható futási idővel rendelkező programot igazán nagy
értékekre elsőként 10.000.000-ig futattam. A gyorsabb
futás érdekében csak minden 100000. lépéskor frissül a ciklusváltozó értékét
folyamatosan tartalmazó Edit mező. Ebben az intervallumban 9 darab
egyensúlyszámot talált a gép. Aztán 100 millió, majd 1 milliárd volt a felső
határ. A 11. egyensúlyszám után már majdnem feladtam, nincs tovább, ennyire
volt képes a program. Íme az első 11 egyensúlyszám:
Nem nyugodtam, szerettem volna a 12.-et is
megkeresni. Néhány milliárd fölötti futtatás közben (hiszen nem egy-két percről
van szó), a már megtalált számokat figyelve, arra jöttem rá, hogy az egymást
követő számok hányadosa 6 körüli. Elő egy Excel táblát, nézzük mi a hányados:
Az eredmény elég
meggyőző abban a tekintetben, hogy a hányados 14 tizedes jegyre a 10. számtól
ugyanaz és előtte sem nagyon különbözik egymástól. Úgy néz ki, mintha a
hányadosok egy konvergens sorozatot alkotnának. Csak körülbelüli értékeket
számolva a 1,55 milliárd - 1,7 milliárd keresési intervallum következett, és
teljes volt a siker, kevesebb mint egy óra alatt
meglett a 12. egyensúlyszám:
Természetesen később a köztes értékekre is
lefuttattam a programot, nem talált további egyensúlyszámokat, tehát a
megtalált valóban a
A táblában kövérrel írva a felszorzással
számított értékek vannak. És valóban, jól látható, hogy a 12. számot pontosan
adja. A továbbiak pontosságát már csak más algoritmusokat alkalmazó program
segítségével lehet ellenőrizni. Jelen program ugyanis 3 milliárd környékén, a
számok összegének kiszámításánál túlcsordul. Mindenesetre nagy valószínűséggel
a 13. egyensúlyszám
A program listája:
unit UEgyenSzam;
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls, Grids;
type
TfmEgyenSzam = class(TForm)
lbEgyenSzam: TLabel;
btKilepes: TButton;
lbKezdo: TLabel;
edKezdo: TEdit;
lbVeg: TLabel;
edVeg: TEdit;
sgEgyenSzam: TStringGrid;
btKeres: TButton;
lbKesz: TLabel;
edSzamol: TEdit;
Label1: TLabel;
edStart: TEdit;
Label2: TLabel;
edStop: TEdit;
Function Osszeg(E, U: Int64): Int64;
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btKeresClick(Sender: TObject);
procedure edKezdoChange(Sender: TObject);
procedure edVegChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
fmEgyenSzam: TfmEgyenSzam;
Kezdo, Veg: LongInt;
DNev: String;
FText: Text;
implementation
{$R *.dfm}
procedure TfmEgyenSzam.btKilepesClick(Sender: TObject);
begin
Close;
end;
procedure TfmEgyenSzam.FormCreate(Sender: TObject);
begin
With sgEgyenSzam Do
Begin
Cells[0,0]:= 'Sorsz.:';
ColWidths[0]:= 40;
ColWidths[2]:= 280;
Cells[1,0]:= 'Egyensúlyszám:';
Cells[2,0]:= 'Az összeg:';
End;
Kezdo:= StrToInt(edKezdo.Text);
Veg:= StrToInt(edVeg.Text);
end;
procedure TfmEgyenSzam.edKezdoChange(Sender: TObject);
Var Kod: Integer;
begin
Val(edKezdo.Text,Kezdo,Kod);
end;
procedure TfmEgyenSzam.edVegChange(Sender: TObject);
Var Kod: Integer;
begin
Val(edVeg.Text,Veg,Kod);
end;
Function TfmEgyenSzam.Osszeg(E, U: Int64): Int64;
Begin
Osszeg:= Round((E+U)*(U-E+1)/2);
End;
procedure TfmEgyenSzam.btKeresClick(Sender: TObject);
Var N: Word;
I, J: LongInt;
S1, S2, E, K, V: Int64;
Van: Boolean;
begin
edStart.Text:= TimeToStr(GetTime); edStart.Repaint;
edStop.Text:= ''; edStop.Repaint;
lbKesz.Caption:= ' '; lbKesz.RePaint;
edSzamol.Text:= '1'; edSzamol.Repaint;
N:= 1;
With sgEgyenSzam Do
Begin
For I:= 0 To ColCount-1 Do For J:= 1 To RowCount-1 Do Cells[I,J]:= '';
sgEgyenSzam.RePaint;
If Kezdo<2 Then Kezdo:= 2;
For I:= Kezdo To Veg Do
Begin
edSzamol.Text:= IntToStr(I);
If (I<10000) Or (I Mod 100000=0) Then edSzamol.Repaint;
S1:= Osszeg(1,I-1);
E:= Round(1.4*I); V:= Round(1.5*I); Van:= False;
While (E<=V) And Not Van Do
Begin
K:= (E+V) Div 2;
S2:= Osszeg(I+1,K);
If S1=S2 Then Van:= True Else
If S1<S2 Then V:= K-1 Else E:= K+1;
End;
If Van Then
Begin
Cells[0,N]:= IntToStr(N)+'.';
Cells[1,N]:= IntToStr(I);
Cells[2,N]:= IntToStr(S1);
sgEgyenSzam.Repaint; Inc(N);
End;
End;
End;
lbKesz.Caption:= 'Kész';
edStop.Text:= TimeToStr(GetTime);
DNev:= 'EgyenSzam.txt'; N:= 1;
AssignFile(FTExt,DNev); ReWrite(FText);
With sgEgyenSzam Do While Cells[0,N]<>'' Do
Begin
WriteLn(FText,Cells[0,N],' ',Cells[1,N],'-',Cells[2,N]);
Inc(N);
End;
CloseFile(FText);
end;
end.