główna strona  Pascal
czyli prawo
pierwszych połączeń
 
Kiedy nie masz w danej dziedzinie żadnych doświadczeń, pierwsze doświadczenie staje się modelem, punktem odniesienia dla następnych. Tak w moim przypadku było z Pascalem. Historia uczy, że niewłaściwy pierwszy krok może być dla człowieka przekleństwem. Ja mogę tylko wyrazić szczerą wdzięczność mym nauczycielom za tę przygodę.
moje pierwsze programy
program hetmany;

const rozmiar = 8;
type wiersze = 1..rozmiar;
type kolumny = 1..rozmiar;
var het : array [wiersze] of kolumny;
var licznik : integer;

procedure rysuj;
var w : wiersze;
var k : kolumny;

  procedure kreska;
  var k : kolumny;
  begin
    write('+');
    for k := 1 to rozmiar do write('---+');
    writeln;
  end;

begin
  licznik := licznik+1; writeln(licznik);
  kreska;
  for w := 1 to rozmiar do
  begin
    write('|');
    for k := 1 to rozmiar do
      if (het[w] = k) then write(' * |')
                      else write('   |');
    writeln;
    kreska;
  end
end;

function pasuje(wrs : wiersze; kol : kolumny) : Boolean;
var ok : Boolean;
var w : wiersze;
begin
  het[wrs] := kol;
  ok := true;
  w := 1;
  while ok and (w < wrs) do
  begin
    if (het[w] = kol)
      or (w+het[w] = wrs+kol)
      or (w-het[w] = wrs-kol)
      then ok := false;
    w := w+1;
  end;
  pasuje := ok;
end;

procedure postaw(w : wiersze);
var k : kolumny;
begin
  for k := 1 to rozmiar do
    if pasuje(w, k) then
      if (w = rozmiar) then rysuj else postaw(w+1);
end;

begin
  licznik := 0; postaw(1);
  writeln; writeln('czekam na klawisz [Enter]'); readln;
end.
Uczestnicząc w tygodniowym intensywnym kursie Pascala byłem tak niecierpliwy, że zacząłem pisać swój pierwszy program zanim poznałem wszystkie elementy potrzebne do jego ukończenia. Lecz nim lekcje dobiegły końca, mój program był już gotowy.
W owym czasie zaprzątała mi głowę łamigłówka z gazety: ustawić na szachownicy 8 hetmanów tak, by żaden żadnego nie atakował. Spędziłem kilka godzin nad szachownicą i znalazłem rozwiązanie, nurtowało mnie jednak pytanie, ile jest wszystkich możliwych ustawień. Czułem, że bez komputera nigdy się tego nie dowiem.
Pierwszą myślą było odwzorowanie szachownicy w postaci dwuwymiarowej tablicy, w której komórkach określona wartość oznaczałaby hetmana, a inna – jego brak. Próba skonstruowania algorytmu przeglądającego taką tablicę w poszukiwaniu kolizji po wierszach, kolumnach i przekątnych przyprawiła mnie o migrenę. Nie tędy droga! Potrzebny jest pomysł, a jego źródłem bywa bystre spostrzeżenie. Czyż nie wystarczy pamiętać pozycji każdego hetmana na wyimaginowanej szachownicy? A więc po parze współrzędnych dla każdego z ośmiu hetmanów?
Skoro hetman atakuje po liniach poziomych i pionowych, to znaczy że żadne dwie pary współrzędnych nie mogą mieć tego samego numeru wiersza ani kolumny. A skoro atakuje także po przekątnych, to nie mogą mieć też równej różnicy numeru wiersza i kolumny ani ich sumy. To wydawało się rozsądne i bardzo upraszczało wykrywanie kolizji. Pozostało zdecydować, czy przechowywać te współrzędne w ośmiu dwupolowych rekordach, czy lepiej w ośmiu dwuelementowych tablicach, a może w dwóch ośmioelementowych, czy wreszcie w jednej dwuwymiarowej tablicy 2x8?
Ta chwila zawahania stworzyła małą lukę w wartkim rozumowaniu, w którą szczęśliwie wdarł się nowy pomysł. Skoro dwa hetmany nie mogą przebywać w tym samym wierszu, to nie trzeba w ogóle im tego umożliwiać. Niech każdy dostanie na własność swój wiersz, a numer hetmana będzie taki sam jak numer wiersza. Wówczas do zapamiętania (i dopasowania) pozostanie tylko jedna współrzędna.
W tym momencie poczułem słodkie podniecenie, czując, że jestem na dobrej drodze, a problem w magiczny sposób sam się upraszcza. Nie tracąc więc czasu przystąpiłem do zapisywania programu.
Najdłuższa w tym programie procedura rysuj służy do prezentacji wyników. Pomocnicza funkcja pasuje ustawia danego hetmana w żądanej kolumnie i sprawdza kolizje z poprzednio ustawionymi. A cały algorytm przeszukiwania tak naprawdę zawarty jest w procedurze postaw, która pokazuje prawdziwą moc nowoczesnego języka programowania.
 
Drugi program demonstruje ukryte właściwości liczb. Przebiegając kolejne liczby naturalne ruchem spiralnym poczynając od centralnego punktu i stawiając znaczki w miejscu liczb pierwszych odkrywamy tajemnicze konstelacje, których istnienia nikt by się nie domyślał. Niektórzy twierdzą, że to odcisk palca Boga.
 
Niklaus Wirth w genialny sposób połączył w Pascalu elegancję, prostotę składni, pozwalającą budować szybkie jednoprzebiegowe kompilatory, walory dydaktyczne wyrabiające w programistach dobre nawyki oraz siłę i skuteczność w realizacji zadań. Dla mnie Pascal to więcej niż język programowania - to filozofia wytyczająca pewną drogę, to wzorzec dobrego obyczaju w dżungli informatycznych wynaturzeń.
 
Oba programy uruchomisz bez problemu w środowisku Lazarus. Względem oryginałów z 1978 roku dodałem na końcu oczekiwanie na klawisz, aby obraz wyniku nie uciekał z ekranu. Wtedy nie było to potrzebne, gdyż program dostarczało się na kartach perforowanych, a rezultat wypełzał z drukarki wierszowej, więc nie było mowy o żadnej interakcji z użytkownikiem.
 
Dobra wiadomość z ostatniej chwili:
Jeżeli masz telefon lub tablet z Android™-em, PascalGUI pozwoli cieszyć się przedstawionymi tu programami. W tym przypadku można znów usunąć wiersz oczekiwania na klawisz, bo wyniki nie uciekają z ekranu.
program pierwsze;

const rozmiar = 79;
const limit = rozmiar * rozmiar;
const rzm2 = rozmiar div 2;

var strona : array [-rzm2..rzm2, -rzm2..rzm2] of char;
var sito : array [1..limit] of char;
var i, j, k, n : integer;

procedure dawaj(dx, dy : integer);
begin
  i := i+dx; j := j+dy;
  strona[i, j] := sito[k];
  k := k+1;
end;

begin
  { przygotowanie tablicy liczb pierwszych }
  for i := 1 to limit do sito[i] := '*';
  for i := 2 to limit div 2 do
  begin
    if sito[i] <> ' ' then
    begin
      j := i+i;
      while j <= limit do
      begin
        sito[j] := ' ';
        j := j+i;
      end
    end
  end;
  { zwinięcie liczb pierwszych w kłębek }
  i := 0; j := 0; k := 1; n := 0;
  dawaj(0, 0);
  while n < rzm2 do
  begin
    dawaj(1, 0);
    while (j <  n) do dawaj( 0, 1);
    while (i > -n) do dawaj(-1, 0);
    while (j > -n) do dawaj( 0,-1);
    while (i <  n) do dawaj( 1, 0);
    n := n+1;
  end;
  { prezentacja wyniku }
  for i := -rzm2 to rzm2 do
  begin
    for j := -rzm2 to rzm2 do write(strona[i, j]);
    writeln;
  end;
  writeln; writeln('czekam na klawisz [Enter]'); readln;
end.
 
opiekun: Janusz Wiśniewski :: rejestracja odwiedzin 2386 gości
desk