Anda di halaman 1dari 22

MODUL KULIAH ALGORITMA PEMROGRAMAN 13

PENGERTIAN REKURSI
Rekursi adalah kemampuan suatu rutin untuk memanggil dirinya Sendiri. Jadi
dengan rekursi memungkinkan untuk memanggil suatu prosedur/fungsi dari
dalam prosedur/fungsi itu sendiri. Rekursi diperlukan karena ada beberapa
permasalahan yang akan jauh lebih mudah diselesaikan dengan rekursi.
Masalah yang umum muncul dalam rekursi adalah adanya eksekusi yang tidak
pernah berhenti yang berakibat pada habisnya memori tumpukan sehingga
komputer menjadi Hang.

Faktorial
Salah satu contoh yang paling sering digunakan untuk menjelaskan rekursi
adalah fungsi faktorial. Fungsi faktorial dari bilanngan bulat positif n
didefinisikan sebagai berikut :

 N .( N -1) 2 1, jika N  1


N! 
 1, jika N  0,1

Contoh :
4! = 4.3!
4! = 4.3.2!
4! = 4.3.2.1
4! = 24

Berikut ini algoritma untuk menghitung nilai n faktorial.


Algoritma FAKTORIAL
DESKRIPSI:
1. Baca n
2. Jika n = 0 atau n =1 maka faktorial = 1.
3. Jika n >= 2 maka faktorial = n* faktorial (n-1)
4. Tulis faktorial.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 14

Sesuai dengan definisinya, sub rutin fungsi penghitung faktorial dapat ditulis
sebagai berikut :

Function faktorial (N : byte) :longint;


Begin
If ( N=0 ) or ( N=1 ) then
Faktorial := 1
Else
Faktorial := N*Faktorial( N-1 );
End;

Untuk memahami bagaimana proses rekursi untuk faktorial berlangsung,


tambahkan dua pernyataan untuk menulis nilai N sebagaimana ditampilkan
oleh bagan sub rutin berikut :
Function faktorial (N : byte) : longint;
Begin
Writeln (‘Atas : ‘, N);
If (N = 0) or (N = 1) then
Faktorial := 1
Else
Faktorial := N*Faktorial( N-1 );
Writeln (‘Bawah ‘, N);
End;

Untuk N = 4, sub rutin di atas akan menampilkan keluaran seperti berikut :

Atas : 4
Atas : 3
Atas : 2
Atas : 1
Bawah 1
Bawah 2
Bawah 3
Bawah 4

Penjelasan mengenai keluaran sub rutin di atas adalah sebagai berikut. Mula-
mula N = 4, fungsi Faktorial dipanggil, berarti di layar muncul „Atas:4‟. Karena N
tidak sama dengan 0 atau 1, maka fungsi Faktorial dipanggil dengan parameter
3. Karena N juga tidak sama dengan 0 atau1, maka di layar muncul „Atas : 3‟.
Demikian seterusnya sampai N = 1 dan di layar muncul „Atas:1‟.

Setelah N = 1, tidak ada lagi proses rekursi, jadi di layar akan tertulis „Bawah 1‟.
Berikutnya fungsi Faktorial (1) akan mengembalikan proses pada
pemanggilnya, yaitu Faktorial (2), dan pada layar akan tertulis „Bawah 2‟.
Demikian seterusnya sampai proses kembali pada Faktorial (4) yang tidak lain
adalah pemanggil fungsi rekursi yang pertama kali.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 15

Untuk lebih jelasnya, dapat dilihat aliran proses seperti yang terlihat pada
Gambar 1.

Faktorial (4) 4 * 6 = 24

Faktorial (4)

4*faktorial (3) 3*2=6

Faktorial (3)

3*faktorial (2) 2*1=2

Faktorial (2)

2*faktorial (1) 1

Faktorial (1)

Gambar 1. Pemanggilan fungsi Faktorial untuk n = 4.

Bilangan Fibonacci

Fungsi lain yang dapat di ubah ke bentuk rekursi adalah penghitung bilangan
Fibonacci. Bilangan Fibonacci dapat didefinisikan sebagai berikut :

 Fn 1  Fn  2 , untuk N  2

Fn   1, untuk N = 1

 0, untuk N = 0

Berikut ini adalah barisan bilangan Fibonacci mulai dari n = 1.

1 1 2 3 5 8 13 21 …

Sebagai contoh, untuk n = 4, proses penghitungan Fibonacci dapat dilakukan


sebagai berikut :

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 16

F4 = f3 +f2
F4 = (f2+f1) + (f1+f0)
F4 = (f1+f0)+f1) + (f1+f0)
F4 = ((1+0) +1) + (1+0)
F4 = 3

Algoritma bilangan Fibonacci dapat ditulis sebagai berikut:


Algoritma FIBONACCI
DESKRIPSI:
1. Baca n
2. Jika n = 0 atau n =1 maka fibonacci = 1.
3. Jika n >= 2 maka fibonacci = fibonacci (n-1) + fibonacci (n-2)
4. Tulis fibonacci.

Sub rutin fungsi untuk bilangan Fibonacci yang dituliskan dalam bahasa Pascal
dapat ditulis sebagai berikut :

Function Fibonacci( n:byte ) : longint;


Begin
If ( n = 0 ) then
Fibonacci := 0
Else if ( n = 1 ) then
Fibonacci := 1
Else
Fibonacci := Fibonacci( n–1 ) + Fibonacci( n–2 );
End;

Perhatikan bahwa ada dua kali pemanggilan fungsi Fibonacci, yaitu Fibonacci
(n-1) dan Fibonacci (n-2). Berikut proses penghitungan bilangan Fibonacci
untuk n = 4 (Gambar.2.).

Fibonacci (4)

Fibonacci (3) Fibonacci (2)

Fibonacci (2) Fibonacci (1) Fibonacci (1) Fibonacci (0)

Fibonacci (1) Fibonacci (0)


Gambar 2. Proses Penghitungan Fibonacci (4).

Dari Gambar 2. dapat diketahui bahwa jumlah pemanggilan fungsi Fibonacci


akan bertambah secara eksponensial. Untuk contoh, jika n=2 maka hanya

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 17

terjadi dua kali pemanggilan fungsi Fibonacci. Sementara itu, untuk n=3 terjadi
4 kali pemanggilan fungsi Fibonacci. Demikian juga untuk n=4 terjadi 8 kali
pemanggilan fungsi Fibonacci. Dengan demikian, untuk n=5, dapat dihitung
bahwa jumlah pemanggilan fungsi Fibonacci adalah sebanyak 8+4+2 = 14 kali.

Faktor Persekutuan Terbesar (FPB)


Di sini, akan dijelaskan bagaimana menghitung FPB dengan rekursi. Prinsip
kerjanya mirip dengan algoritma Euclid, yaitu membagi dua bilangan bulat
secara terus-menerus sampai sisa pembaginya adalah 0.

Algoritma FPB
Diberikan dua buah bilangan bulat tak-negatif m dan n (m  n). Carilah pembagi
bersama terbesar (pbt), dari kedua bilangan tersebut, yaitu bilangan bulat positif
terbesar yang habis membagi m dan n.

DESKRIPSI:
1. Jika n = 0 maka
FPB = m adalah jawabannya; stop.
tetapi jika m  0,
lanjutkan ke langkah 2.
2. Bagilah m dengan n dan misalkan FPB adalah sisanya.
3. Ganti nilai m dengan nilai n dan nilai n dengan nilai FPB, lalu ulang kembali ke
langkah 1.

Sub rutin fungsi untuk algoritma FPB di atas adalah


Function FPB (m,n : integer): integer;
Begin
If ( m = 0 ) then
FPB := n
Else if ( m < n ) then
FPB := FPB ( n,m )
Else
FPB := FPB ( m mod n, n );
End;

Penjelasan jalannya proses pencarian FPB untuk bilangan bulat positif 228 dan
90 adalah sebagai berikut:
Pertama-tama, terjadi pemanggilan fungsi FPB (228,90). Karena m>n, maka
terjadi pemanggilan fungsi FPB (228 mod 90,90) atau FPB (48,90). Karena
m<n, maka terjadi pemanggilan fungsi FPB (90,48). Demikian seterusnya
sampai pemanggilan fungsi FPB (0,6), yang artinya proses selesai karena m
bernilai 0. Dengan demikian FPB yang dicari sama dengan n atau 6. Ilustrasi
proses di atas dapat dilihat dalam Gambar 3. berikut ini.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 18

FPB (228,90)

FPB (48,90)

FPB (90,48)

FPB (42,48)

FPB (48,42)

FPB (6,42)

FPB (0,6)

FPB (42,6)

Gambar 3. Proses pencarian FPB Dari 228 dan 90.

Beberapa Contoh Pemakaian Rekursi.

Kasus 1. Permutasi
Untuk menampilkan semua permutasi dari N karakter ‟A‟, ‟B‟, ‟C‟, dan
seterusnya, diperlukan rekursi karena proses permutasi akan menampilkan
karakter yang sama secara berulang. Sebagai contoh, untuk n=2, permutasi
yang ada adalah :
A B
B A

Buatlah subrutin untuk menghitung permutasi yang ada dari sejumlah karakater
sebagaimana dimaksudkan di atas.

Penyelesaian:

Algortima
Bentuk algoritma dan sub rutin prosedur untuk membangkitkan permutasi dari
N karakter adalah sebagai berikut

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 19

Algoritma PERMUTASI
{ Diberikan nilai N suatu bilangan bulat tak-negatif. Carilah permutasi N karakter
Alpahabet. }

DEKLARASI
Const Max = 10
Type TPermutasi = array [ 1..10 ] of char

Procedure DoPermutasi (output A: TPermutasi ; input mulai :byte);


{ menghitung permutasi yang ada dari sejumlah N karakater }

DEKLARASI
i : byte;
Temp : char;

DESKRIPSI

If ( mulai = N ) then
for i ← 1 to N do
write ( A [ i ] )
endfor
else
for i ← mulai to N do
temp ← A [ i ]
A[i] ← A [ mulai ]
A [ mulai ] ← temp
DoPermutasi (A, mulai +1)
endfor
endif

Implementasi Algortima dalam Pascal

Const
Max = 10;

Type
TPermutasi = array[ 1..10 ] of char;

Var
Ax : TPermutasi;
i, N : byte;

Procedure DoPermutasi (A: TPermutasi ; mulai :byte);


Var
i : byte;
Temp : char;
Begin
If ( mulai = N ) then

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 20

Begin
for i := 1 to N do
write ( A [ i ] );
writeln;
end;
else
begin
for i : = mulai to N do
begin
temp := A [ i ];
A [ i ] := A [ mulai ];
A [ mulai ] := temp;
DoPermutasi (A, mulai +1);
end;
end;
end;
begin
write ( ‘Masukkan N : ‘ );
readln ( N );
for i := 1 to N do
Ax [ i ] := chr ( i + 64 );
DoPermutasi ( Ax, 1 );
end.

Keluaran dari program di atas adalah sebagai berikut :

Masukkan N : 2

AB
BA

Masukkan N : 3

ABC
ACB
BAC
BCA
CAB
CBA

Untuk N = 3, proses dari program di atas dapat diilustrasikan seperti yang


ditampilkan dalam Gambar 4.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 21

DoPermutasi (A,1)

ABC

i=1 i=2 i=3

DoPermutasi (A,2) DoPermutasi (A,2) DoPermutasi (A,2)

ABC BAC CAB

i=2 i=3 i=2 i=3 i=2 i=3

DoPermutasi (A,3) DoPermutasi (A,3) DoPermutasi (A,2) DoPermutasi (A,3) DoPermutasi (A,3) DoPermutasi (A,3)

ABC ACB BAC BCA CAB CBA

Mulai = N Mulai = N Mulai = N Mulai = N Mulai = N Mulai = N

ABC ACB BAC BCA CAB CBA

Gambar 4. Membangkitkan Permutasi

Kasus 2. Bujur Sangkar “Ajaib” 2m x 2m


Permasalahan bujur sangkar “ajaib” merupakan permasalahan untuk
mendapatkan jumlah bilangan yang sama untuk setuap baris, kolom, dan
diagonal utama sebuah bujur sangkar. Bujur sangkar ajaib berukuran nxn
dengan n = 2m, 2<m<6, dua contohnya adalah:

16 2 3 13 46 56 3 25 32 6 49 43
5 11 10 8 63 37 18 12 13 23 36 58
9 7 6 12 17 11 64 38 35 57 14 24
4 14 15 1 4 26 45 55 50 44 31 5
60 34 21 15 10 20 39 61
Bujur Sangkar Ajaib 4 x 4. 41 51 8 30 27 1 54 48
7 29 42 52 53 47 28 2
22 16 59 33 40 62 9 19

Bujur Sangkar Ajaib 8 x 8.

Perhatikan bahwa bilangan bulat merupakan masukan untuk program yang


akan dibuat. Sedangkan keluaran dari program tersebut adalah larik dua
dimensi yang merupakan bujur sangkar ajaib 2m x 2m.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 22

Penyelesaian:

Pengisian bujur sangkar ajaib berukuran 2m x 2m dilakukan dengan cara tukar-


menukar elemen. Adapun caranya adalah
Pertama-tama, isilah bujur sangkar tersebut dengan bilangan dari 1 sampai
dengan 22m. Kemudian tukarkan empat pasang elemen yang ada dengan cara
sebagai berikut :
1. X11 X44
2. X14 X41
3. X22 X33
4. X23 X32

Algoritma
Algoritma penyusunan bujur sangkar ajaib 2m x 2m secara umum dapat
dituliskan sebagai berikut :
1. Isi bujur sangkar dengan nilai 1 sampai dengan 22m secara berurutan.
2. Bagi bujur sangkar menjadi berukuran 2m / 2 x 2m / 2.
3. Beri nama elemen-elemen bujur sangkar dengan kode X11, X12, X13, …..,
X44.
4. Lakukan penukaran berikut : X11 X44, X14 X41,
X22 X33 dan X23 X32.
5. Apabila setiap elemen bujur sangkar masih terdiri dari bujur sangkar lagi,
artinya m > 1, kerjakan lagi baris 2.

Implementasi Algortima dalam Pascal


Berikut ini adalah contoh program untuk menampilkan bujur sangkar 2m x 2m :

const
Max = 128;
Valid : set of byte = [ 4, 8, 16, 32, 64, 128 ];
var
i, j, N : byte;
A : array [ 1..Max, 1..Max ] of word;

procedure Tukar ( var x, y : word );


var
temp : word;
begin
temp := x;
x := y;
y := temp;
end;

procedure TukarKotak ( dimensi, ofsx, ofsy : byte );


var
i, j : byte;
center2 : byte;
center4 : byte;

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 23

begin
center2 := dimensi div 2;
center4 := dimensi div 4;
for i := 1 to center4 do
for j := 1 to center4 do
begin
Tukar ( A [ ofsy + j, ofsx + i ],
A [ dimensi + ofsy – center4 + j,
dimensi + ofsy – center4 + i ] );
Tukar ( A [ ofsy + center4 + j,ofsx+center4 + i ],
A [ ofsy + center2 + j,ofsx+center2 + i ] );
Tukar ( A [ ofsy + center2 + j,ofsx+center2 + i ],
A [ ofsy + center4 + j,ofsx+center4 + i ] );
Tukar ( A [ ofsy + j,dimensi + ofsx – center4 + i ],
A [ dimensi + ofsy–center4 + j, ofsx + i ]);
end;
if ( center2 > 2 ) then
begin
TukarKotak ( Center2, ofsx, ofsy );
TukarKotak ( Center2, ofsx + center2, ofsy );
TukarKotak ( Center2, ofsx, ofsy + center2 );
TukarKotak ( Center2, ofsx + center2,
ofsy + center2 );
end;
end;
begin
write ( ‘Masukkan dimensi bujur sangkar : ‘ );
readln ( N );
if ( not ( N in Valid )) then
begin
writeln ( ‘Dimensi bujur sangkar tidak valid’ );
halt;
end;

fillchar ( a, sizeof ( a ), 0 );

for i := 1 to N do
for j := 1 to N do
A [ i, j ] := ( i – 1 ) = N + j;
TukarKotak ( N, 0, 0 );

for i := 1 to N do
begin
for j := 1 to N do
write ( A [ i, j ] : 3, ‘ ‘ ); writeln;
end;
end.

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 24

Keluaran program di atas adalah sebagai berikut :

Masukkan dimensi bujur sangkar : 4


16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
Masukkan dimensi bujur sangkar : 8

46 56 3 25 32 6 49 43
63 37 18 12 13 23 36 58
17 11 64 38 35 57 14 24
4 26 45 55 50 44 31 5
60 34 21 15 10 20 39 61
41 51 8 30 27 1 54 48
7 29 42 52 53 47 28 2
22 16 59 33 40 62 9 19

Kasus 3. Permainan 8 Ratu


Permainan 8 (delapan) ratu adalah permainan yang menggunakan sebuah
papan catur dengan delapan buah ratu. Persoalan dalam permainan ini terletak
pada upaya setiap ratu yang ada tidak saling menghabiskan/menyerang.

Penyelesaian :

Algoritma
Algoritma penyelesaian persoalan 8 ratu dapat dituliskan secara garis besar
seperti berikut :
1. i 1. x 1.
2. Ulangi baris 3 sampai dengan 8 sampai semua posisi sudah diserang ratu
lain atau ( i > 8 ).
3. Cari posisi yang masih mungkin ditempati pada kolom ke-x.
4. Jika masih ada posisi yang mungkin kerjakan baris 5 sampai dengan 8.
5. Letakkan ratu pada posisi yang mungkin tersebut.
6. Jika ( x < 8 ) kerjakan baris 7 dan 8.
7. Kerjakan kembali baris 2 untuk kolom berikutnya, yaitu x + 1.
8. Jika ratu tidak dapat diletakkan pada kolom berikutnya, hapus ratu pada
posisi ini.

Implementasi Algortima dalam Pascal


Berikut ini adalah contoh program untuk menyelesaikan persoalan 8 ratu di
atas:

const
Max = 8;

var

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 25

Hor, Ver, Dia1, Dia2 : longint;


Pos : array [ 1..Max ] of byte;

procedure InitData;
var
i : byte;
begin
Hor := 0;
Ver := 0;
Dia1 := 0;
Dia2 := 0;
FillChar ( Pos, sizeof ( Pos ), 0 );
end;

procedure LetakRatu ( x, y : byte );


begin
Pos [ y ] := x;
Hor := Hor or ( 1 shl ( x – 1 ));
Ver := Ver or ( 1 shl ( y – 1 ));
Dia1 := Dia1 or ( 1 shl ( Max – y + x – 1 ));
Dia2 := Dia2 or ( 1 shl ( x + y – 2 ));
end;

procedure AmbilRatu ( x, y : byte );


begin
Pos [ y ] := 0;
Hor := Hor and not ( 1 shl ( x – 1 ));
Ver := Ver and not ( 1 shl ( y – 1 ));
Dia1 := Dia1 and not ( 1 shl ( Max – y + x – 1 ));
Dia2 := Dia2 and not ( 1 shl ( x + y – 2 ));
end;

function DoProcess ( x : byte ) : boolean;


var
i : byte;
penuh : boolean;
begin
i := 1;
penuh := false;
repeat
if (Hor and ( 1 shl ( i – 1 )) = 0 ) and
(Ver and ( 1 shl ( x – 1 )) = 0 ) and
(Dia1 and ( 1 shl ( Max – x + i – 1 )) = 0 )
and
(Dia2 and ( 1 shl ( x + i – 2 )) = 0 ) then
begin
LetakRatu ( i, x );

if ( x < 8 ) then

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 26

begin
penuh := DoProcess ( x + 1 );
if ( not penuh ) then
AmbilRatu ( i, x );
end
else
penuh := true;
end;
inc ( i );
until ( i > 8 ) or ( penuh );
DoProcess := penuh;
end;

procedure TulisHasil;
var
i, j : integer;
begin
for i := 1 to Max do
begin
for j := 1 to Max do
if ( Pos [ i ] = j ) then
write ( ‘ 1 ‘ )
else
write ( ‘ 0 ‘ );
writeln;
end;
end;

begin
InitData;
DoProcess ( 1 );
TulisHasil;
end.

Keluaran program di atas adalah sebagai berikut :


1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 27

Kasus 4. Labirin
Permasalahan Labirin merupakan permasalahan untuk mencari jalan terpendek
dari titik tertentu ke titik lain melalui labirin.

Cara termudah untuk menyimpan labirin adalah dengan membuat suatu larik
dua dimensi dengan ukuran NumRow untuk baris dan NumCol untuk kolom.
Masing-masing elemen larik bertipe rekaman yang memiliki empat anggota,
yaitu Utara, Barat, Selatan, Timur. Keempat anggota rekaman ini masing-
masing digunakan untuk menyimpan ada tidaknya tembok di sebelah Utara,
Barat, Selatan, dan Timur.

Di sini, akan digunakan metode trial and error. Prinsipnya, mula-mula di coba
satu arah, misalkan ke utara. Jika gagal di coba arah lain, misalkan ke timur.
Jika masih gagal di coba lagi arah lain. Demikian seterusnya.

Algoritma pencarian jalan keluar labirin dapat dituliskan secara garis


besar sebagai berikut :
1. X StartX. Y StartY.
2. Coba posisi ( X, Y ).
3. Jika ( X = StopX ) dan ( Y = StopY ) maka catat jalur yang dilalui dan cek
apakah jumlah langkah lebih kecil dari jumlah langkah minimum sebelumnya
atau tidak.
4. Jika posisi ( Y – 1, X ) dapat ditempati, kerjakan baris 2 untuk posisi ini.
5. Jika posisi ( Y, X - 1 ) dapat ditempati, kerjakan baris 2 untuk posisi ini.
6. Jika posisi ( Y + 1, X ) dapat ditempati, kerjakan baris 2 untuk posisi ini.
7. Jika posisi ( Y, X + 1 ) dapat ditempati, kerjakan baris 2 untuk posisi ini.

Berikut ini adalah contoh program untuk memecahkan labirin yang disimpan
pada file maze.in.

Program Labirin;
Uses Crt, Dos;
Const
MaxMaze = 20;
MaxRoute = 1000;

type
TRoute = record
Row, Col : byte;
end;
TDirection = record
Utara, Selatan, Barat, Timur : boolean;
end;

var
NumRow, NumCol : byte;
StartX, StartY : byte;
StopX, StopY :byte;

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 28

Maze : array [ 1..MaxMaze, 1..MaxMaze ] of TDirection;


Visit : array [ 1..MaxMaze, 1..MaxMaze ] of boolean;
NumRoute : integer;
Route : array [ 1..MaxRoute ] of TRoute;
MinNumRoute : integer;
MinRoute ; array [ 1..MaxRoute ] of TRoute;

procedure InitData;
var
i, j, : integer;
FileA : text;
Ch : char;
Buffer : array [1..2*MaxMaze + 1,
1..2 * MaxMaze + 1 ] of char;
begin
Assign ( FileA, ‘Maze.in’ );
Reset ( FileA );
Readln ( FileA, NumRow, NumCol );
Readln ( FileA, StartY, StartX );
Readln ( FileA, StopY, StopX );

FillChar ( Buffer, sizeof ( Buffer ), 0 );


FillChar ( Visit, sizeof ( Visit ), 0 );
FillChar ( Maze, sizeof ( Maze ), 0 );
FillChar ( Route, sizeof ( Route ), 0 );
FillChar ( MinRoute, sizeof ( MinRoute ), 0 );
NumRoute := 1;
MinNumRoute := MaxRoute;

for i := 1 to 2 * NumRow + 1 do
begin
for j := 1 to 2 * NumCol + 1 do
begin
Read ( FileA, ch );
if ( ch <> #13 ) then
Buffer [ i, j ] := ch
else
break;
end;
repeat
Read ( FileA, ch );
until ( ch <> #13 );
end;

for i := 1 to 2 * NumRow + 1 do
begin
for j := 1 to 2 * NumCol + 1 do
begin
if ( i mod 2 = 0 ) and ( j mod 2 = 0 ) then

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 29

begin
Maze [ i div 2, j div 2 ] . Utara := (
Buffer [ i – 1, j ] = ‘-‘ );
Maze [ i div 2, j div 2 ] . Selatan :=
( Buffer [ i + 1, j ] = ‘-‘ );
Maze [ i div 2, j div 2 ] . Timur := (
Buffer [ i, j + 1 ] = ‘ | ‘ );
Maze [ i div 2, j div 2 ] . Barat := (
Buffer [ i, j - 1 ] = ‘ | ‘ );
end;
end;
end;
Close ( FileA );
end;

procedure DoRecursive ( x, y : byte; dx, dy : shortint );


begin
Visit [ y, x ] := true;
Route [ NumRoute ] . Row := y;
Route [ NumRoute ] . Col := x;
inc ( NumRoute );
x := x + dx;
y := y + dy;

if ( x = StopX ) and ( y = StopY ) then


begin
Route [ NumRoute ] . Row := y;
Route [ NumRoute ] . Col := x;
if ( MinNumRoute > NumRoute ) then
begin
Move ( Route, MinRoute, sizeof ( Route ) );
MinNumRoute := NumRoute;
end;
exit;
end;

if ( y > 1 ) and ( dy <> 1 ) and


( not Visit [ y – 1, x ] ) and
( not Maze [ y, x ] . Utara ) then
begin
DoRecursive ( x, y, 0, -1 );
doc ( NumRoute );
end;
Visit [ y, x ] := false;

if ( y < NumRow ) and ( dy <> -1 ) and


( not Visit [ y + 1, x ] ) and
( not Maze [ y, x ] . Selatan ) then
begin

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 30

DoRecursive ( x, y, 0, 1 );
dec ( NumRoute );
end;
Visit [ y, x ] := false;

if ( x > 1 ) and ( dx <> 1 ) and ( not Visit [ y, x –


1 ] ) and
( not Maze [ y, x ] . Barat ) then
begin
DoRecursive ( x, y, -1, 0 );
doc ( NumRoute );
end;
Visit [ y, x ] := false;

if ( x < NumCol ) and ( dx <> -1 ) and


( not Visit [ y, x + 1 ] ) and
( not Maze [ y, x ] . Timur ) then
begin
DoRecursive ( x, y, 1, 0 );
dec ( NumRoute );
end;
Visit [ y, x ] := false;
end;

pocedure PrintRoute;
var
i : integer;
begin
Writeln;
if ( MinNumRoute = MaxRoute ) then
Writeln ( ‘ Tidak dapat diselesaikan’ )
else
begin
Write ( MinRoute[1].Row, ‘,’, MinRoute[1].Col);
for i := 2 to MinNumRoute do
Write (‘–‘, MinRoute[i].Row, ‘,‘ , MinRoute[i].Col);
end;
end;

begin
InitData;
DoRecursive ( 1, 1, 1, 0 );
PrintRoute;
end.

Keluaran program di atas adalah sebagai berikut :

1,1 - 1, 2 - 1,3 - 2,3 - 3,3 - 3,4 - 3,5 - 4,5 - 5,5 - 6,5 - 6,6

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 31

Kasus 5. Permainan Isi Botol 3 dan 5 Liter

Misalkan tersedia 2 (dua) botol A dan B yang masing-masing berukuran 3 liter


dan 5 liter. Bagaimana upaya untuk mendapatkan sebuah isi botol tersebut
dengan ukuran 4 (empat). Untuk menyelesaikan persoalan botol ini ada
beberapa hal yang dapat dilakukan, yaitu :
a. Mangisi botol A dengan air sampai penuh.
b. Membuang seluruh isi botol A.
c. Memindahkan isi botol A ke botol B sampai botol B penuh.
d. Mengisi botol B dengan air sampai penuh.
e. Membuang seluruh isi botol B.
f. Memindahkan isi botol B ke botol A sampai botol A penuh.

Berikut ini adalah contoh program untuk memecahkan permasalahan botol di


atas. Pada program ini, A dan B adalah volume maksimum dari botol A dan
botol B; C adalah volume air yang diharapkan; Ax dan Bx adalah jumlah air
dalam botol A dan B saat ini.

Const
Max = 100;

ValidMove : array [ 1..6, 1..6 ] of boolean =


(( false, false, true, true, true, false ),
( false, false, false, true, true, true),
( true, false, false, false , true, false ),
( true, true, false, false, false, true ),
( true, true, true, false, false, false ),
( false, true, false, true, false, false ));

var
A, B, C : byte;
Ax, Bx : byte;
i : byte;
Gerak : array [ 1..Max ] of byte;
Buffer : array [ 1..Max ] of byte;
Minimum : byte;
Jumlah : byte;
Sukses : boolean;

procedure DoProcess ( g : byte );


var
j : byte;
begin
if ( Jumlah > Max ) or Sukses then
exit;

inc ( Jumlah );
Gerak [ Jumlah ] := g;

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 32

case ( g ) of
1 : if ( Ax = 0 ) and ( Bx <> B ) then
Ax := A
else
exit;
2 : if ( Ax = A ) and ( Bx > 0 ) then
Ax := 0
else
exit;
3 : if ( Ax > 0 ) then
begin
Bx := Bx + Ax;
if ( Bx > B ) then
begin
Ax := Bx – B;
Bx := B;
end
else
Ax := 0;
end
else
exit;

4 : if ( Bx = 0 ) and ( Ax <> A ) then


Bx := B
else
exit;
5 : if ( Bx = B ) and ( Ax > 0 ) then
Bx := 0
else
exit;
6 : if ( Bx > 0 ) then
begin
Ax := Ax + Bx;
if ( Ax > A ) then
begin
Bx := Ax – A;
Ax := A;
end
else
Bx := 0;
end
else
exit;
end;

if ( Ax = C ) or ( Bx = C ) then
Sukses := true

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 33

else if ( Ax < A ) or ( Bx < B ) then


begin
for j := 1 to 6 do
if ( ValidMove [ g, j ] ) then
begin
DoProcess ( j );
if ( not Sukses ) then
doc ( Jumlah );
end;
end;
end;

begin
A := 5;
B := 3;
C := 4;
Fillchar ( Gerak, sizeof ( Gerak ), 0 );
Minimum := Max;
Fillchar ( Buffer, sizeof ( Buffer ), 0 );

i := 1;
while ( i <= 6 ) do
begin
Ax := 0;
Bx := 0;
Jumlah := 0;
Sukses := false;
DoProcess ( i );
if ( Sukses ) and ( Minimum > Jumlah ) then
begin
Minimum := Jumlah;
Move ( Gerak, Buffer, sizeof ( Gerak ) );
end;
inc ( i );
end;

if ( Minimum = Max ) then


writeln ( ‘Gagal’ )
else
begin
for i := 1 to Minimum do
begin
case ( Buffer [ i ] ) of
1 : writeln ( ‘Isi A’ );
2 : writeln ( ‘Buang A’ );
3 : writeln ( ‘Pindah A ke B’ );
4 : writeln ( ‘Isi B’ );
5 : writeln ( ‘Buang B‘ );
6 : writeln ( ‘Pindah B ke A’ );

JURUSAN MATEMATIKA Kreasi oleh Jack2k6


MODUL KULIAH ALGORITMA PEMROGRAMAN 34

end;
end;
end;
end.

Keluaran program di atas adalah sebagai berikut :

Isi A
Pindah A ke B
Buang B
Pindah A ke B
Isi A
Pindah A ke B

Sebenarnya program ini juga dapat digunakan untuk memecahkan kasus lain,
misalnya bagaimana cara mendapatkan air 9 liter dari botol 10 dan 13 liter.
Untuk itu ubahlah tiga baris pertama dari program utama di atas, yaitu pada
pemberian nilai A, B, dan C, menjadi seperti berikut :

A := 10;
B := 13;
C := 9;

Keluaran program di atas adalah sebagai berikut :

Isi B
Pindah B ke A
Buang A
Pindah B ke A
Isi B
Pindah B ke A
Buang A
Pindah B ke A
Isi B
Pindah B ke A

JURUSAN MATEMATIKA Kreasi oleh Jack2k6

Anda mungkin juga menyukai