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 12. Ha a sejtés igaz a hányadosok sorozatára, akkor a következő egyensúlyszámokat egy Excel tábla segítségével megjósolhatjuk:

 

 

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 9.228.778.026, a 14. egyensúlyszám pedig 53.789.260.175. Legalábbis ezektől nem túlságosan sokkal különbözik. (Akinek kedve van, nosza, írjon rá ellenőrző programot. Lehet, hogy rövidesen én is szolgálok egy ilyennel.)

 

A program listája:

 

unit UEgyenSzam;

interface

uses
  Windows, MessagesSysUtilsVariantsClasses,

  GraphicsControlsFormsDialogsStdCtrlsGrids;

type
  TfmEgyenSzam = class(TForm)
    lbEgyenSzamTLabel;
    btKilepesTButton;
    lbKezdoTLabel;
    edKezdoTEdit;
    lbVegTLabel;
    edVegTEdit;
    sgEgyenSzamTStringGrid;
    btKeresTButton;
    lbKeszTLabel;
    edSzamolTEdit;
    Label1: TLabel;
    edStartTEdit;
    Label2: TLabel;
    edStopTEdit;
    Function Osszeg(E, U: Int64): Int64;
    procedure btKilepesClick(SenderTObject);
    procedure FormCreate(SenderTObject);
    procedure btKeresClick(SenderTObject);
    procedure edKezdoChange(SenderTObject);
    procedure edVegChange(SenderTObject);
  private
    Private declarations }
  public
    Public declarations }
  end;

var
  fmEgyenSzamTfmEgyenSzam;
  KezdoVegLongInt;
  DNevString;
  FTextText;

implementation

{$R *.dfm}

procedure TfmEgyenSzam.btKilepesClick(SenderTObject);
begin
  Close;
end;

procedure TfmEgyenSzam.FormCreate(SenderTObject);
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(SenderTObject);
Var Kod: Integer;
begin
  Val(edKezdo.Text,Kezdo,Kod);
end;

procedure TfmEgyenSzam.edVegChange(SenderTObject);
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(SenderTObject);
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.