Fakocka
Egy rokoni látogatás alkalmával akadt a kezembe egy fakocka, amely gyakorlatilag egy doboz volt, melynek a tömör belsejét kisebb kockákra illetve hasábokra vágták szét (a játékot a NET-en ördöglakat kategóriába is besorolják). Én gyanútlanul kiborítottam az egészet és megpróbáltam visszarakni, úgy ahogy eredetileg volt, azaz hézagmentesen és szabályos, teljes kitöltéssel. Mondanom sem kell, nem sikerült. Azért, hogy mindenki számára egyértelmű legyen, hogy milyen játékról is beszélek, lefényképeztem összerakott állapotban is és kiszedve a nagy kockából a kisebb elemeket. Íme:
Összerakott fakocka
Szétszedett állapot
Mielőtt továbblépnénk, végezzünk egy kis számvetést. A képekről kiderül, hogy a teljes kocka belső éle 5 egységnyinek tekinthető, azaz a térfogata 125 térfogategység. Nézzük, hogyan jön ez össze a kisebb elemekből:
1*1*1 |
kocka |
5 db |
5*1 |
5 térfogategység |
1*2*4 |
hasáb |
6 db |
6*8 |
48 térfogategység |
2*2*3 |
hasáb |
6 db |
6*12 |
72 térfogategység |
Összesen: |
17 db |
|
125 térfogategység |
Láthatjuk, hogy a számvetés eredményes. A kis kockák és hasábok térfogatának összege a nagy kocka térfogatával megegyezik, azaz elvileg (de az első képre tekintve látható, hogy gyakorlatilag sincs) nincs semmi akadálya a hézagmentes visszarakásnak. Mivel többszöri próbálkozásomra sem sikerült a kockát eredeti állapota szerint összerakni, arra gondoltam, írok rá programot, ami majd megkeresi a helyes elrendezést.
Első gondolat: szisztematikusan keresse meg a megoldást, az összes eset végigjárásával. Ehhez határozzuk meg, hogy hányféleképpen helyezhetjük a kisebb elemeket a nagy kockába. Az összes lehetséges elhelyezések számát a következő szorzat adja:
(125/1)*(124/2)*…*(121/5)*(120/1)*(119/2)*…*(115/6)*(114/1)*(113/2)*…*(109/6)* 36*66
A 125 helyből először ki kell választani 17-et, majd az 5+6+6-féle elemet ezeken el kell helyezni, ugyanakkor azt is figyelembe kell venni, hogy a kis kockákat egyféleképpen, a hasábokat viszont 3- illetve 6-féle pozícióban helyezhetjük a tér kiválasztott pontjába. A képlet első része a 125 alatt a 17 (azaz 125 elemnek a 17-ed osztályú ismétlés nélküli kombinációja) és a 17 elemnek az ismétléses (5-6-6) permutációja szorzatának egyszerűsítése. A második részben azt vettük figyelembe, hogy az egyikféle (2*2*3-ast) 6 darab hasábot 3-, a másik 6 darabot (az 1*2*4-est) 6-féleképen helyezhetjük a tér egy adott pontjába (csak pozitív koordinátájú elhelyezéssel számoltunk). Készítsünk ennek kiszámítására egy kis Excel táblázatot:
A C oszlopot a C2 húzásával töltöttük fel, melynek tartalma: =A2/B2*C1. Majd a szerkesztőlécben látható módon a C18-at módosítottuk. Azt kaptuk, hogy az összes esetek száma valamivel több, mint egy nagyságrenddel megközelíti a milliárd negyedik hatványát! Ennyi esetet (mert mi van, ha csak az utolsó lépésekben kapjuk meg a megoldást) a mai számítógépekkel végignézni lehetetlen, pontosabban túlságosan hosszú ideig tartana.
Második gondolat: próbáljuk megkeresni a megoldást – a sokszor már eredményesnek bizonyult – ütközésmentesítő algoritmussal. Ez az algoritmus egy olyan genetikus algoritmus, amelynek csak egyetlen egyede van, nincs benne keresztezés, csak két egymás után létrejött egyed között van szelekció, van viszont mutáció. Az algoritmus menete a következő:
– az állapottérben felveszünk egy darab egyedet, véletlen elemekkel,
– egy függvénnyel megállapítjuk az egyed jóságát (hibapontjainak vagy ütközéseinek számát),
– véletlenül kiválasztjuk az egyed egy elemét és megjegyezzük a választást a hibaponttal együtt,
– véletlen értékre megváltoztatjuk a kiválasztott elemet (mutáció),
– újra megállapítjuk az egyed jóságát és megjegyezzük,
– ha az új hibaszám nem rosszabb az előzőnél, akkor a véletlen választást megtartjuk, ha rosszabb, akkor az elem értékét az előzőre visszaállítjuk (szelekció),
– a mutációt és szelekciót addig folytatjuk (áttérünk a következő generációra), amíg vagy 0 hibát nem kapunk (megoldottuk a feladatot), vagy egy előre adott generációszámot el nem érünk.
Ha arra gondolunk, hogy gyakorlatilag csak egyetlen megoldás keresünk a sok-sok milliárd közül (elvileg 24 van, de ezek egymás transzformáltjai), akkor túlságosan gyors eredményre nem számíthatunk. A paramétereket, amelyek a megengedett hibaszám ismétléseit jelentik, illetve az összes lépések számát elég magasan, milliós illetve milliárdos nagyságrendben kell majd keresni. Ehhez persze elég gyors gépre is szükség lesz, hogy értelmes idő alatt megoldás szülessen.
A következő táblázatban a paraméterek 100.000.000 lépés alapján alakultak ki úgy, hogy minden hibaértékre ugyanaz az Ismétlések maximuma:
Ismétlés maximuma |
Legjobb |
Hiba maximuma |
Változás maximuma |
Újra |
10.000 |
11 / 1 db |
34 |
9.999 |
16.231 |
50.000 |
4 / 1 db |
14 |
49.936 |
934 |
100.000 |
4 / 8 db |
12 |
99.575 |
520 |
200.000 |
4 / 7 db |
10 |
198.372 |
285 |
500.000 |
4 / 4 db |
10 |
499.954 |
136 |
1.000.000 |
4 / 5 db |
10 |
974.700 |
72 |
2.000.000 |
4 / 4 db |
6 |
1.805.416 |
39 |
3.000.000 |
4 / 3 db |
6 |
1.887.272 |
29 |
5.000.000 |
4 / 1 db |
6 |
4.140.705 |
16 |
Egy kis értelmezés:
Ismétlések maximuma: maximálisan ennyiszer ismétlődhetett egy hibaszám, ha ezt elérte, akkor teljesen új véletlen egyedet generált. Mivel a legjobbnak látszó beállítás a 100000 volt, a legtöbb esetben ezzel a paraméterrel futtattam a programot.
Legjobb: mekkora volt a legjobb elrendezés hibaszáma és hány darabolt állított elő belőle.
Hiba maximuma: amely hibaszám a legtöbbször szerepelt a generálás során.
Változás maximuma: amikor ugyanolyan hibaszám mellett az eljárás keres megoldást, előfordult hogy például 3 milliós maximum esetén 1.887.272 lépés után talált olyat, ami jobb megoldást jelentett és cserélt egyedet a program.
Újra: ennyiszer generált teljesen új elemet a program a teljes futási idő alatt.
Néhány futtatási kép:
Magyarázat:
A baloldali rácsban a nagy kocka öt szelete látható Z=1-től Z=5-ig.
A zöldeskék területen lévő számok jelentése: 24 – egységkocka helye, 3 – 1*2*4-es hasáb, 2 – 2*2*3-as hasáb helye.
Piros háttérrel rendelkező számok jelentése: olyan számok, amelyek nem esnek a [2,3,24] halmazba, illetve üres a mező. A piros mezők száma az egyed hibapontjainak a száma.
Ezen a képernyőn a milliárdnyi lépés után sem talált megoldást a program. A két hibapont egy üres helyből és egy kettős átfedésből adódik. Az X=3, Y=3 és Z=3 hely üres, az X=4, Y=4 és Z=5 helyen két 3-as kódú hasáb ütközése található. A középső rácsban az aktuális elhelyezkedést és helyzeteket látjuk és azt, hogy hány Esetben szerepelt a kérdéses elem eredményes cserében.
Ezen a képernyőn egy eredményes futtatást láthatunk, mely kb. 6 percig tartott. A baloldali rácsban nincs piros mező. A legjobb érték közvetlenül a megoldás megtalálása előtt 2 hibapont volt. A jobboldali rácsban azt láthatjuk, hogy az egyes hibapont értékek a teljes futási idő alatt hányszor fordultak elő. Megjegyezném, hogy a páratlan hibapontok száma sokkal kisebb, mint a párosoké. A középső nagy listadobozban a milliónkénti aktuális hibapontok láthatók.
A megoldásból az ügyesebbeknek csak annyit kell megjegyezni, hogy a kis kockák a megoldásban a nagy kocka testátlójában foglalnak helyet. Ha ennek tudatában végezzük az összerakást, akkor van remény arra, hogy a gépi eredmény elemzése nélkül is sikerül.
Akiknek még így is nehéz feladat a kocka összerakása, segítségül egy másik programban a megoldást géppel, axonometriában megrajzoltattam. Ebből is néhány screenshot:
A kocka alsólapján (az X-Z síkon) nyugvó elemek
A kocka felső (az X-Z síkkal párhuzamos) lapján nyugvó elemek
Azok az elemek (belsők), amelyek az előző két elrendezésből kimaradtak
A kocka baloldali lapján (az Y-Z síkon) nyugvó elemek
A kocka jobboldali (az Y-Z síkkal párhuzamos) lapján nyugvó elemek
Azok az elemek (belsők), amelyek az előző két elrendezésből kimaradtak
Íme a kockakirakó program listája:
(* 1*1*1 = 1 5*1 = 5 Index: 1 - 5 Helyzet: 1 Azonositó: 24
1*2*4 = 8 6*8 = 48 Index: 6 - 11 Helyzet: 1 - 6 Azonositó: 3
2*2*3 = 12 6*12 = 72 Index: 12 - 15 Helyzet: 1 - 3 Azonositó: 2
--------------------
Osszesen: 125
**)
unit UFKK;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids;
Const VH1=6;
VH2=3;
type
TfmFKK = class(TForm)
btKilepes: TButton;
sgMoni: TStringGrid;
lbKesz: TLabel;
edHiba: TEdit;
edBest: TEdit;
sgElem: TStringGrid;
lbHiba: TLabel;
btStart: TButton;
edLSz: TEdit;
edStart: TEdit;
edStop: TEdit;
ldHelp: TListBox;
lbElso: TLabel;
lbMasod: TLabel;
lbHarmad: TLabel;
edUjra: TEdit;
edMValt: TEdit;
sgIsm: TStringGrid;
lbBest: TLabel;
lbLSz: TLabel;
lbValtMax: TLabel;
lbUjra: TLabel;
edMax: TEdit;
lbMax: TLabel;
lbIMax: TLabel;
edIMax: TEdit;
Procedure UresTer;
Procedure ElemDel(N: Word);
Procedure ElemTerbe(N: Word);
Procedure Kepre;
Procedure ElemMake(N,IH: Word);
Procedure General;
Function Utkozesek: Word;
procedure btKilepesClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sgMoniDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure btStartClick(Sender: TObject);
procedure sgElemDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure edMaxChange(Sender: TObject);
procedure edIMaxChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TElem=Record
X, Y, Z: Integer; //kezdohely
H: Word; //helyzet
Eset: LongInt; //eredmenyes cserek szama
End;
var
fmFKK: TfmFKK;
Ter: Array[-2..8,-2..8,-2..8] Of Word;
ElemT, BT: Array[0..17] Of TElem;
Kezd, RKezd: Word;
IsmT: Array[0..35] Of Int64;
Max: Int64;
IMax, PMax: LongInt;
implementation
{$R *.dfm}
procedure TfmFKK.btKilepesClick(Sender: TObject);
begin
Close;
end;
procedure TfmFKK.sgMoniDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgMoni.Canvas.Brush Do
Begin
If Not((gdSelected In State) Or (gdFixed In State)) Then
Begin
If (StrToInt(sgMoni.Cells[0,ARow])>0) And
(StrToInt(sgMoni.Cells[0,ARow])<6) And
(StrToInt(sgMoni.Cells[1,ARow])>0) And
(StrToInt(sgMoni.Cells[1,ARow])<6) And (ACol>4) And (ACol<10) Then
Color:= clAqua Else Color:= clWindow;
If (StrToInt(sgMoni.Cells[0,ARow])>0) And
(StrToInt(sgMoni.Cells[0,ARow])<6) And
(StrToInt(sgMoni.Cells[1,ARow])>0) And
(StrToInt(sgMoni.Cells[1,ARow])<6) And (ACol>4) And (ACol<10) And
(sgMoni.Cells[ACol,ARow]<>'2') And
(sgMoni.Cells[ACol,ARow]<>'3') And
(sgMoni.Cells[ACol,ARow]<>'24') Then
Color:= clRed;
End;
If (gdSelected In State) Then Color:= clYellow;
End;
sgMoni.Canvas.TextRect(Rect,Rect.Left+6,Rect.Top,sgMoni.Cells[ACol,ARow]);
If gdFocused In State Then sgMoni.Canvas.DrawFocusRect(Rect);
end;
procedure TfmFKK.sgElemDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
With sgElem.Canvas.Brush Do
Begin
If Not((gdSelected In State) Or (gdFixed In State)) Then
If (ARow In [1..5]) Or (ARow In [12..17]) Then
Color:= clAqua Else Color:= clWindow;
If (gdSelected In State) Then Color:= clYellow;
End;
sgElem.Canvas.TextRect(Rect,Rect.Left+3,Rect.Top+1,sgElem.Cells[ACol,ARow]);
If gdFocused In State Then sgElem.Canvas.DrawFocusRect(Rect);
end;
procedure TfmFKK.FormCreate(Sender: TObject);
Var I,J: Integer;
begin
Randomize; Kezd:=1; RKezd:=17;
Max:= StrToInt(edMax.Text); IMax:= StrToInt(edIMax.Text); PMax:= IMax;
With sgMoni Do
Begin
ColWidths[1]:= 28; RowHeights[0]:= 14;
Cells[0,0]:= 'Y'; Cells[1,0]:= 'Z/X';
For I:= -2 To 8 Do Cells[I+4,0]:= IntToStr(I);
For I:= -2 To 8 Do For J:= -2 To 8 Do Cells[0,(I+2)*11+J+3]:= IntToStr(J);
For I:= -2 To 8 Do For J:= -2 To 8 Do Cells[1,(I+2)*11+J+3]:= IntToStr(I);
RowHeights[RowCount-1]:= 0; Row:= RowCount-1;
End;
With sgElem Do
Begin
ColWidths[ColCount-1]:= 48;
ColWidths[4]:= 48;
Cells[1,0]:= 'X'; Cells[2,0]:= 'Y'; Cells[3,0]:= 'Z';
Cells[4,0]:= 'Helyzet';
For I:= 1 To 17 Do Cells[0,I]:= IntToStr(I); Cells[ColCount-1,0]:= 'Eset';
RowHeights[RowCount-1]:= 0; Row:= RowCount-1;
End;
With sgIsm Do
Begin
ColWidths[0]:= 32;
Cells[0,0]:= 'Hiba'; Cells[1,0]:= 'Eset';
For I:= 0 To 35 Do Cells[0,I+1]:= IntToStr(I);
RowHeights[RowCount-1]:= 0; Row:= RowCount-1;
End;
UresTer; For I:= 1 To 17 Do ElemT[I].Eset:= 0; Kepre;
end;
Procedure TfmFKK.UresTer;
Var I, J, K: Integer;
Begin
For I:= -2 To 8 Do For J:= -2 To 8 Do For K:= -2 To 8 Do Ter[I,J,K]:= 0;
End;
Procedure TfmFKK.ElemDel(N: Word); //N. elemet kiveszi a terbol
Var D: Word;
Begin
With ElemT[N] Do
Case N Of
1..5: Begin
D:= 24;
Dec(Ter[X,Y,Z],D);
End;
6..11: Begin //1*2*4
D:= 3;
Case H Of
1: Begin //1-2-4
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y+1,Z ],D);
Dec(Ter[X, Y, Z+1],D); Dec(Ter[X, Y+1,Z+1],D);
Dec(Ter[X, Y, Z+2],D); Dec(Ter[X, Y+1,Z+2],D);
Dec(Ter[X, Y, Z+3],D); Dec(Ter[X, Y+1,Z+3],D);
End;
2: Begin //1-4-2
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y, Z+1],D);
Dec(Ter[X, Y+1,Z ],D); Dec(Ter[X, Y+1,Z+1],D);
Dec(Ter[X, Y+2,Z ],D); Dec(Ter[X, Y+2,Z+1],D);
Dec(Ter[X, Y+3,Z ],D); Dec(Ter[X, Y+3,Z+1],D);
End;
3: Begin //4-1-2
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y, Z+1],D);
Dec(Ter[X+1,Y, Z ],D); Dec(Ter[X+1,Y, Z+1],D);
Dec(Ter[X+2,Y, Z ],D); Dec(Ter[X+2,Y, Z+1],D);
Dec(Ter[X+3,Y, Z ],D); Dec(Ter[X+3,Y, Z+1],D);
End;
4: Begin //2-1-4
Dec(Ter[X, Y, Z ],D); Dec(Ter[X+1,Y, Z ],D);
Dec(Ter[X ,Y, Z+1],D); Dec(Ter[X+1,Y, Z+1],D);
Dec(Ter[X ,Y, Z+2],D); Dec(Ter[X+1,Y, Z+2],D);
Dec(Ter[X ,Y, Z+3],D); Dec(Ter[X+1,Y, Z+3],D);
End;
5: Begin //2-4-1
Dec(Ter[X, Y, Z ],D); Dec(Ter[X+1,Y, Z ],D);
Dec(Ter[X, Y+1,Z ],D); Dec(Ter[X+1,Y+1,Z ],D);
Dec(Ter[X, Y+2,Z ],D); Dec(Ter[X+1,Y+2,Z ],D);
Dec(Ter[X, Y+3,Z ],D); Dec(Ter[X+1,Y+3,Z ],D);
End;
6: Begin //4-2-1
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y+1,Z ],D);
Dec(Ter[X+1,Y, Z ],D); Dec(Ter[X+1,Y+1,Z ],D);
Dec(Ter[X+2,Y, Z ],D); Dec(Ter[X+2,Y+1,Z ],D);
Dec(Ter[X+3,Y, Z ],D); Dec(Ter[X+3,Y+1,Z ],D);
End;
End;
End;
12..17: Begin //2*2*3
D:= 2;
Case H Of
1: Begin //2-2-3
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y, Z+1],D);
Dec(Ter[X, Y, Z+2],D); Dec(Ter[X+1,Y, Z ],D);
Dec(Ter[X+1,Y, Z+1],D); Dec(Ter[X+1,Y, Z+2],D);
Dec(Ter[X, Y+1,Z ],D); Dec(Ter[X, Y+1,Z+1],D);
Dec(Ter[X, Y+1,Z+2],D); Dec(Ter[X+1,Y+1,Z ],D);
Dec(Ter[X+1,Y+1,Z+1],D); Dec(Ter[X+1,Y+1,Z+2],D);
End;
2: Begin //2-3-2
Dec(Ter[X, Y, Z ],D); Dec(Ter[X, Y+1,Z ],D);
Dec(Ter[X, Y+2,Z ],D); Dec(Ter[X+1,Y, Z ],D);
Dec(Ter[X+1,Y+1,Z ],D); Dec(Ter[X+1,Y+2,Z ],D);
Dec(Ter[X, Y, Z+1],D); Dec(Ter[X, Y+1,Z+1],D);
Dec(Ter[X, Y+2,Z+1],D); Dec(Ter[X+1,Y, Z+1],D);
Dec(Ter[X+1,Y+1,Z+1],D); Dec(Ter[X+1,Y+2,Z+1],D);
End;
3: Begin //3-2-2
Dec(Ter[X, Y, Z ],D); Dec(Ter[X+1,Y, Z ],D);
Dec(Ter[X+2,Y, Z ],D); Dec(Ter[X, Y+1,Z ],D);
Dec(Ter[X+1,Y+1,Z ],D); Dec(Ter[X+2,Y+1,Z ],D);
Dec(Ter[X, Y, Z+1],D); Dec(Ter[X+1,Y, Z+1],D);
Dec(Ter[X+2,Y, Z+1],D); Dec(Ter[X, Y+1,Z+1],D);
Dec(Ter[X+1,Y+1,Z+1],D); Dec(Ter[X+2,Y+1,Z+1],D);
End;
End;
End;
End;
End;
Procedure TfmFKK.ElemMake(N,IH: Word); //N. elemet keszit H helyzetben
Begin
With ElemT[N] Do
Begin
H:= IH;
Case N Of
1..5: Begin X:= Random(11)-2; Y:= Random(11)-2; Z:= Random(11)-2 End;
6..11: Begin X:= Random(8)-2; Y:= Random(8)-2; Z:= Random(8)-2 End;
12..17: Begin X:= Random(9)-2; Y:= Random(9)-2; Z:= Random(9)-2 End;
End;
End;
End;
Procedure TfmFKK.General;
Var I: Word;
Begin
For I:= 1 To 5 Do ElemMake(I,1);
For I:= 6 To 11 Do ElemMake(I,Random(VH1)+1);
For I:= 12 To 17 Do ElemMake(I,Random(VH2)+1);
For I:= 1 To 17 Do ElemTerbe(I);
End;
Procedure TfmFKK.ElemTerbe(N: Word); //N. elemet beteszi a terbe
Var D: Word;
Begin
With ElemT[N] Do
Case N Of
1..5: Begin
D:= 24;
Inc(Ter[X,Y,Z],D);
End;
6..11: Begin //1*2*4
D:= 3;
Case H Of
1: Begin //1-2-4
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y+1,Z ],D);
Inc(Ter[X, Y, Z+1],D); Inc(Ter[X, Y+1,Z+1],D);
Inc(Ter[X, Y, Z+2],D); Inc(Ter[X, Y+1,Z+2],D);
Inc(Ter[X, Y, Z+3],D); Inc(Ter[X, Y+1,Z+3],D);
End;
2: Begin //1-4-2
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y, Z+1],D);
Inc(Ter[X, Y+1,Z ],D); Inc(Ter[X, Y+1,Z+1],D);
Inc(Ter[X, Y+2,Z ],D); Inc(Ter[X, Y+2,Z+1],D);
Inc(Ter[X, Y+3,Z ],D); Inc(Ter[X, Y+3,Z+1],D);
End;
3: Begin //4-1-2
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y, Z+1],D);
Inc(Ter[X+1,Y, Z ],D); Inc(Ter[X+1,Y, Z+1],D);
Inc(Ter[X+2,Y, Z ],D); Inc(Ter[X+2,Y, Z+1],D);
Inc(Ter[X+3,Y, Z ],D); Inc(Ter[X+3,Y, Z+1],D);
End;
4: Begin //2-1-4
Inc(Ter[X, Y, Z ],D); Inc(Ter[X+1,Y, Z ],D);
Inc(Ter[X ,Y, Z+1],D); Inc(Ter[X+1,Y, Z+1],D);
Inc(Ter[X ,Y, Z+2],D); Inc(Ter[X+1,Y, Z+2],D);
Inc(Ter[X ,Y, Z+3],D); Inc(Ter[X+1,Y, Z+3],D);
End;
5: Begin //2-4-1
Inc(Ter[X, Y, Z ],D); Inc(Ter[X+1,Y, Z ],D);
Inc(Ter[X, Y+1,Z ],D); Inc(Ter[X+1,Y+1,Z ],D);
Inc(Ter[X, Y+2,Z ],D); Inc(Ter[X+1,Y+2,Z ],D);
Inc(Ter[X, Y+3,Z ],D); Inc(Ter[X+1,Y+3,Z ],D);
End;
6: Begin //4-2-1
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y+1,Z ],D);
Inc(Ter[X+1,Y, Z ],D); Inc(Ter[X+1,Y+1,Z ],D);
Inc(Ter[X+2,Y, Z ],D); Inc(Ter[X+2,Y+1,Z ],D);
Inc(Ter[X+3,Y, Z ],D); Inc(Ter[X+3,Y+1,Z ],D);
End;
End;
End;
12..17: Begin //2*2*3
D:= 2;
Case H Of
1: Begin //2-2-3
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y, Z+1],D);
Inc(Ter[X, Y, Z+2],D); Inc(Ter[X+1,Y, Z ],D);
Inc(Ter[X+1,Y, Z+1],D); Inc(Ter[X+1,Y, Z+2],D);
Inc(Ter[X, Y+1,Z ],D); Inc(Ter[X, Y+1,Z+1],D);
Inc(Ter[X, Y+1,Z+2],D); Inc(Ter[X+1,Y+1,Z ],D);
Inc(Ter[X+1,Y+1,Z+1],D); Inc(Ter[X+1,Y+1,Z+2],D);
End;
2: Begin //2-3-2
Inc(Ter[X, Y, Z ],D); Inc(Ter[X, Y+1,Z ],D);
Inc(Ter[X, Y+2,Z ],D); Inc(Ter[X+1,Y, Z ],D);
Inc(Ter[X+1,Y+1,Z ],D); Inc(Ter[X+1,Y+2,Z ],D);
Inc(Ter[X, Y, Z+1],D); Inc(Ter[X, Y+1,Z+1],D);
Inc(Ter[X, Y+2,Z+1],D); Inc(Ter[X+1,Y, Z+1],D);
Inc(Ter[X+1,Y+1,Z+1],D); Inc(Ter[X+1,Y+2,Z+1],D);
End;
3: Begin //3-2-2
Inc(Ter[X, Y, Z ],D); Inc(Ter[X+1,Y, Z ],D);
Inc(Ter[X+2,Y, Z ],D); Inc(Ter[X, Y+1,Z ],D);
Inc(Ter[X+1,Y+1,Z ],D); Inc(Ter[X+2,Y+1,Z ],D);
Inc(Ter[X, Y, Z+1],D); Inc(Ter[X+1,Y, Z+1],D);
Inc(Ter[X+2,Y, Z+1],D); Inc(Ter[X, Y+1,Z+1],D);
Inc(Ter[X+1,Y+1,Z+1],D); Inc(Ter[X+2,Y+1,Z+1],D);
End;
End;
End;
End;
End;
Function TfmFKK.Utkozesek: Word;
Var I, J, K: Integer;
N: Word;
Begin
N:= 0;
For I:= -2 To 8 Do For J:= -2 To 8 Do For K:= -2 To 8 Do
If (I In [1..5]) And (J In [1..5]) And (K In [1..5]) Then
Begin If Not (Ter[I,J,K] In [2,3,24]) Then Inc(N) End Else
Begin If Ter[I,J,K]>0 Then Inc(N,Ter[I,J,K]) End;
Utkozesek:= N;
End;
Procedure TfmFKK.Kepre;
Var I, J, K: Integer;
Begin
With sgMoni Do
Begin
For K:= -2 To 8 Do For I:= -2 To 8 Do For J:= -2 To 8 Do
If Ter[I,J,K]>0 Then Cells[I+4,J+3+(K+2)*11]:= IntToStr(Ter[I,J,K]) Else
Cells[I+4,J+3+(K+2)*11]:= '.';
End;
With sgElem Do For I:= 1 To 17 Do With ElemT[I] Do
Begin
Cells[1,I]:= IntToStr(X); Cells[2,I]:= IntToStr(Y);
Cells[3,I]:= IntToStr(Z); Cells[4,I]:= IntToStr(H);
Cells[5,I]:= IntToStr(Eset);
End;
End;
procedure TfmFKK.btStartClick(Sender: TObject);
Var AE: TElem;
I, A, H, RH, Best: Word;
N: Int64;
Ism, Ujra, MValt: LongInt;
begin
edStart.Text:= TimeToStr(GetTime); lbKesz.Visible:= False;
N:= 0; UresTer; edHiba.Text:= '0'; edBest.Text:= '0';
General; Kepre;
H:= Utkozesek; edHiba.Text:= IntToStr(H);
Best:= 100; Ism:= 0; RH:= 1000; Ujra:= 1; MValt:= 0; RePaint;
While (H>0) And (N<Max) Do
Begin
Case H Of
0..6: IMax:= PMax;
7..12: IMax:= PMax Div 2;
13..18: IMax:= PMax Div 4;
19..24: IMax:= PMax Div 8;
25..30: IMax:= PMax Div 16;
31..36: IMax:= PMax Div 32;
End;
If H<=35 Then Inc(IsmT[H]);
Inc(N);
If RH=H Then Inc(Ism) Else
Begin
If Ism>MValt Then
Begin MValt:= Ism; edMValt.Text:= IntToStr(MValt); edMValt.Repaint End;
Ism:= 0;
End;
RH:= H; If RH<Best Then Begin Best:= RH; BT:= ElemT End;
A:= Random(RKezd)+Kezd; AE:= ElemT[A]; ElemDel(A);
Case A Of
1..5: ElemMake(A,1);
6..11: ElemMake(A,Random(VH1)+1);
12..17: ElemMake(A,Random(VH2)+1);
End;
ElemTerbe(A);
If Utkozesek>RH Then
Begin ElemDel(A); ElemT[A]:= AE; ElemTerbe(A) End Else
Begin H:= Utkozesek; If H<RH Then Inc(ElemT[A].Eset) End;
If Ism=IMax Then //ujrakezdi
Begin
Inc(Ujra); If MValt=IMax Then MValt:= 0; Ism:= 0; UresTer;
General; H:= Utkozesek;
End;
If N Mod 1000000=0 Then //megjelenit
Begin
Kepre;
For I:= 0 To 35 Do sgIsm.Cells[1,I+1]:= IntToStr(IsmT[I]);
edLSz.Text:= IntToStr(N); edHiba.Text:= IntToStr(H);
edBest.Text:= IntToStr(Best);
ldHelp.Items.Add(IntToStr(H)); edUjra.Text:= IntToStr(Ujra);
edMValt.Text:= IntToStr(MValt); RePaint;
End;
End;
H:= Utkozesek; edLSz.Text:= IntToStr(N); edHiba.Text:= IntToStr(H);
edBest.Text:= IntToStr(Best); Kepre;
If H>0 Then
Begin
UresTer; ElemT:= BT; For I:= 1 To 17 Do ElemTerbe(I); Kepre;
lbKesz.Caption:= 'Vége';
End;
lbKesz.Visible:= True;
edStop.Text:= TimeToStr(GetTime);
end;
procedure TfmFKK.edMaxChange(Sender: TObject);
Var Kod: Integer;
begin
Val(edMax.Text,Max,Kod);
end;
procedure TfmFKK.edIMaxChange(Sender: TObject);
Var Kod: Integer;
begin
Val(edIMax.Text,IMax,Kod);
end;
end.