Laboratorium programowania zad 8

Zadanie z laboratorium programowania na Informatyce UW.

Zadanie 8 (termin wysylania rozwiazan: 7 III 2008, godz. 23:59)

(Grupowanie plikow)

Napisz program, ktory wczyta z wejscia informacje o plikach i podzieli
te pliki na grupy tak, by laczny rozmiar plikow w jednej grupie nie
przekroczyl 700 (megabajtow).

Postac danych:

Na wejsciu programu jest ciag wierszy, z ktorych kazdy opisuje jeden
plik. W wierszu jest kolejno:

- liczba calkowita wyrazajaca rozmiar pliku (w megabajtach)
- jedna spacja
- nazwa pliku (wolno zalozyc, ze moze byc wartoscia typu string)

Postac wyniku:

Program powinien wypisac tyle wierszy, ile grup plikow utworzy.
W kazdym maja sie znalezc nazwy plikow, ktore trafily do danej
grupy, z zachowaniem kolejnosci, w jakiej pliki pojawily sie
na wejsciu. Po kazdej nazwie pliku wypisujemy jedna spacje.

Algorytm:

Program wczytuje z wejscia informacje o kolejnych plikach i dla
kazdego szuka pierwszej grupy, do ktorej plik ten sie zmiesci. Robi
to, przechodzac po utworzonych do tej pory grupach w kolejnosci, w
jakiej te grupy powstawaly. Jesli plik nie miesci sie w zadnej z
dotychczas powstalych grup, tworzymy nowa.

Pliki o rozmiarze przekraczajacym 700 program powinien zignorowac.

Np. dla danych:

400 jeden
10 dwa
300 trzy
500 cztery
111 piec
2222 szesc
222 siedem
1 osiem
10 dziewiec
200 dziesiec

program powinien wypisac:

jeden dwa piec osiem dziewiec 
trzy siedem 
cztery dziesiec 

Wskazowka:

W rozwiazaniu nalezy zbudowac liste grup, a z kazda grupa zwiazac
liste plikow, ktore przydzielilismy do tej grupy.

A oto rozwiązanie:

program zad8;
type

	//Struktura danych to lista dwuwymiarowa. 

	//Tutaj beda przechowywane pliki
	plik_t=^plik_r_t;
	plik_r_t=record
		nastepny:plik_t;
		nazwa:string;
		rozmiar:integer;
	end;
	
	//A tu cale wiersze
	grupa_t=^grupa_r_t;
    grupa_r_t=record 
		wolne:integer; //Wolne miejsce w grupie
		nastepny:grupa_t;
		plik:plik_t; //Pierwszy plik
		ostatni:plik_t;
	end;


var rozmiar:integer;
nazwa:string;
plik,tmp_plik: plik_t;
grupa,pierwszy,tmp_grupa:grupa_t;
znaleziono:boolean;
spacja:char;
begin



	//Tworzymy pierwsza grupe

	new(pierwszy);
	pierwszy^.nastepny:=nil;
	grupa:=pierwszy;
	grupa^.wolne:=700;

	new(grupa^.plik);
	plik:=grupa^.plik;
	plik^.nastepny:=nil;
	plik^.nazwa:='';
	grupa^.ostatni:=plik;
	
	
	//Wczytujemy pliki
	while not EOF do
	begin
		read(rozmiar);
		read(spacja);
		read(nazwa);
		znaleziono:=false;
		grupa:=pierwszy;
		
		//write('Umieszczamy plik "');
		//write(nazwa);
		//write('" o rozmiarze ');
		//write(rozmiar);
		
		if rozmiar<701 then
		begin
			while ((grupa^.nastepny  nil) AND (znaleziono=false))  do
			begin
				//Dla kazdej grupy przechowujemy ilosc wolnego miejsca. dzieki temu nie musimy biegac po tej liscie.
				if ((grupa^.wolne >= rozmiar) AND (znaleziono=false)) then
				begin
					//writeln('    OK. jest grupa z ');
					//write(grupa^.wolne);
					//write(' miejsca');
					//Znalezlismy grupe w ktorej jest wystarczajaco miejsca
						grupa^.ostatni^.nazwa:=nazwa;
						grupa^.ostatni^.rozmiar:=rozmiar;
						new(grupa^.ostatni^.nastepny);
						grupa^.ostatni:=grupa^.ostatni^.nastepny;
						grupa^.ostatni^.nastepny:=nil;
						grupa^.wolne:=grupa^.wolne-rozmiar;
					//Zeby nie wstawiac pliku kilka razy:
					znaleziono:=true;
				end
				else
				begin
					//writeln('    w tej grupie jest za malo. tylko ');
					//write(grupa^.wolne);
					//write(' miejsca');
					grupa:=grupa^.nastepny;
				end
			end;
			
			if (znaleziono=false) then
			begin
				grupa^.wolne:=700-rozmiar;

				//wstawiamy plik:
				
				new(grupa^.plik);
				grupa^.plik^.nazwa:=nazwa;
				grupa^.plik^.rozmiar:=rozmiar;
				
				//Wstawiamy strażnika
				
				new(grupa^.plik^.nastepny);
				grupa^.plik^.nastepny^.nastepny:=nil;
				grupa^.plik^.nastepny^.rozmiar:=0;
				grupa^.plik^.nastepny^.nazwa:='';
				grupa^.ostatni:=grupa^.plik^.nastepny;

				//I straznika dla grupy
				new(grupa^.nastepny);
				grupa:=grupa^.nastepny;
				grupa^.nastepny:=nil;

			end
		end
	end;
	//I pliki wczytane. Wystarczy wypisac.

	
	grupa:=pierwszy;
	while grupa^.nastepnynil do
	begin
		plik:=grupa^.plik;
		while plik^.nastepnynil do
		begin
			write(plik^.nazwa);
			
			if (plik^.nazwa'') then
				write(' ');
			
			//sprzatamy:
			tmp_plik:=plik;
			plik:=plik^.nastepny;
			dispose(tmp_plik);
		end;
		//usuwamy straznika:
		dispose(plik);
		
		writeln();
		
		//Sprzatamy:
		tmp_grupa:=grupa;
		grupa:=grupa^.nastepny;
		dispose(tmp_grupa);
	end;
	dispose(grupa);
	//usuwamy straznika
end.

Laboratorium programowania zad 7

Zadanie 2 z laboratorium programowania na Informatyce UW.

Zadanie 7 (termin wysylania rozwiazan: 29 II 2008, godz. 23:59)

(Kolumny)

Napisz program, ktory wczyta z wejscia tekst i wypisze ten tekst na
wyjscie w dwoch kolumnach rozdzielonych spacja, znakiem kreski pionowej |
i jeszcze jedna spacja.

Jesli liczba wierszy tekstu (N) jest parzysta, w pierszej kolumnie znajdzie
sie kolejno N/2 pierwszych wierszy, a w drugiej N/2 nastepnych. Jesli liczba
wierszy jest nieparzysta, srodkowy wiersz nalezy umiescic na koncu kolumny
pierwszej.

Spacje, kreske i spacje rozdzielajace kolumny nalezy wypisac w tym samym
miejscu kazdego wiersza. Znaki te powinny sie znalezc bezposrednio za koncem
najdluzszego wiersza pierwszej kolumny. Krotsze wiersze pierwszej kolumny
nalezy uzupelnic na koncu odpowiednia liczba spacji.

Np. dla danych:

ala ma kota
to jest kot ali
ela ma psa
azor to pies eli
ola nie ma psa

program powinien wypisac:

ala ma kota     | azor to pies eli
to jest kot ali | ola nie ma psa
ela ma psa      | 

Uwaga:

Wolno zalozyc, ze wiersze tekstu wejsciowego nie sa bardzo dlugie i moga byc
wartoscia typu string. Nie wolno nakladac ograniczenia na liczbe wierszy na
wejsciu.

Wskazowka:

Przed rozpoczeciem wypisywania, tekst z wejscia nalezy wczytac do listy,
ktorej kazdy wezel bedzie przechowywal w polu typu string zawartosc jednego
wiersza.

A oto rozwiązanie:

program zad7;
type

	//Struktura danych to lista dwuwymiarowa. 

	//Tutaj beda przechowywane litery
	litera=^literka;
	literka=record
		nastepny:litera;
		txt:char;
	end;
	
	//A tu cale wiersze
	wiersz=^wier;
    wier=record 
		txt:litera;
		nastepny:wiersz;
		dlugosc:integer;
    end;


var znak:char;
pierwszy,teraz,tmp,prawy:wiersz;
teraz_znak,tmp_znak:litera;
wierszy,dlugosc,najdluzszy,obrotow,i,j,liter:integer;

begin

	if not EOF then
	begin

		//Wczytujemy pierwszy wiersz na liste.
		new(pierwszy);
		pierwszy^.nastepny:=nil;
		teraz:=pierwszy;
		
		read(znak);
		new(teraz^.txt);
		teraz_znak:=teraz^.txt;
		teraz_znak^.nastepny:=nil;
		teraz_znak^.txt:=znak;

		dlugosc:=1;
		//Wczytujemy litery w wierszach az nie trafimy na koniec
		while ((znakchar(10)) AND (not EOF)) do
		begin
			read(znak);
			new(teraz_znak^.nastepny);
			teraz_znak:=teraz_znak^.nastepny;
			teraz_znak^.nastepny:=nil;
			teraz_znak^.txt:=znak;
			dlugosc:=dlugosc+1;

		end;
		wierszy:=1;
		teraz^.dlugosc:=dlugosc;

		
		while not EOF do
		begin
			new(teraz^.nastepny);
			teraz:=teraz^.nastepny;
			teraz^.nastepny:=nil;

			//wczytujemy kolejne wiersze na liste
			
			read(znak);
			new(teraz^.txt);
			teraz_znak:=teraz^.txt;
			teraz_znak^.nastepny:=nil;
			teraz_znak^.txt:=znak;
			//Musimy wiedziec  ile bedzie wierszy
			wierszy:=wierszy+1;
			dlugosc:=1;
			
			//Wczytujemy litery w wierszach az nie trafimy na koniec
			while znakchar(10) do
			begin
				read(znak);
				new(teraz_znak^.nastepny);
				teraz_znak:=teraz_znak^.nastepny;
				teraz_znak^.nastepny:=nil;
				teraz_znak^.txt:=znak;
				dlugosc:=dlugosc+1;
			end;

			//Szukamu najdluzszego wiersza.
			
			teraz^.dlugosc:=dlugosc;

		end;


		najdluzszy:=0;
		//Teraz powinnismy miec wszystko w liscie dwuwymiarowej i dane w zmiennych najdluzszy i wierszy.
		//Zeby wypisywac wszycstko w ten ladny sliczny sposob, znajdziemy wskaznik do pierwszego wiersza prawej kolumny.
		obrotow:=(wierszy div 2) + (wierszy mod 2);
		teraz:=pierwszy;
		//Wskaznik do pierwszego wiersza prawej kolumny
		

			for i:=1 to obrotow do
			begin
				if teraz^.dlugosc>najdluzszy then
					najdluzszy:=teraz^.dlugosc;
				teraz:=teraz^.nastepny;
			end;


		prawy:=teraz;
		teraz:=pierwszy;


		//Wypisujemy.

		for i:=1 to obrotow do
		begin
			tmp:=teraz;
			teraz_znak:=teraz^.txt;
			liter:=0;
				//Wypisujemy litery i caly czas sprzatamy po sobie.
				while teraz_znak  nil do
				begin
					//Mie chcemy przeciez wypisac koncow wierszy /r i /n
					if ((ord(teraz_znak^.txt)10) AND (ord(teraz_znak^.txt)13)) then
						write(teraz_znak^.txt);
					tmp_znak:=teraz_znak;
					teraz_znak:=teraz_znak^.nastepny;
					dispose(tmp_znak);
					liter:=liter+1;
				end;
			
			// spacje
			for j:=liter to najdluzszy-1 do
				write(' ');
			//Kreseczka
			write(' | ');


			teraz:=teraz^.nastepny;
			dispose(tmp);


			//Jesli jest prawy - wypisujemy
			if (prawynil) then
			begin
			
				tmp:=prawy;
				teraz_znak:=prawy^.txt;
				liter:=0;
				//Wypisujemy litery i caly czas sprzatamy po sobie.
				while teraz_znak  nil do
				begin
					write(teraz_znak^.txt);
					tmp_znak:=teraz_znak;
					teraz_znak:=teraz_znak^.nastepny;
					dispose(tmp_znak);
				end;	
		
				prawy:=prawy^.nastepny;
				dispose(tmp);
			end
			else
				writeln();
			//Jesli go nie bylo - musimy znak nowego wiersza.	
			

		end
	end
end.

Laboratorium programowania zad 6

Zadanie 6 z laboratorium programowania na Informatyce UW.

Zadanie 6 (termin wysylania rozwiazan: 22 II 2008, godz. 23:59)

(Odwracanie tekstu)

Napisz program, ktory wczyta z wejscia tekst, a nastepnie wypisze go na
wyjscie, odwracajac kolejnosc wierszy.

Np. dla danych:

program czesc;
begin
  writeln('Czesc')
end.

program powinien wypisac:

end.
  writeln('Czesc')
begin
program czesc;

Wolno zalozyc, ze dlugosci wierszy tekstu na wejsciu nie przekraczaja 65535,
ale nie wolno nakladac ograniczenia na liczbe wierszy.

Wskazowka:

Wczytaj tekst z wejscia i utworz pomocniczy plik binarny, w ktorym po
zawartosci kazdego wiersza znajda sie dwa bajty dlugosci tego wiersza.
Nastepnie przejdz po wierszach zapisanych w tym pliku, w kolejnosci od
ostatniego do pierwszego, i wypisz je na wyjscie.

Pliku pomocniczego nie trzeba usuwac po zakonczeniu pracy programu.

A oto rozwiązanie:

program zad6;
type

	//Struktura danych to lista dwuwymiarowa. Wiersze rosna w tyl, dzieki czemu naturalnie sie odwracaja.

	//Tutaj beda przechowywane litery
	litera=^literka;
	literka=record
		nastepny:litera;
		txt:char;
	end;
	
	//A tu cale wiersze
	wiersz=^wier;
    wier=record 
		txt:litera;
		nastepny:wiersz;
    end;


var znak:char;
pierwszy,teraz,tmp:wiersz;
teraz_znak,tmp_znak:litera;

begin

	teraz:=nil;

	//Wczytujemy kolejne wiersze nowe przystawiajac z przodu. Dzieki temu odwracaja sie naturalnie.
	while not EOF do
	begin
		new(pierwszy);
		pierwszy^.nastepny:=teraz;
		teraz:=pierwszy;
		
		read(znak);
		new(teraz^.txt);
		teraz_znak:=teraz^.txt;
		teraz_znak^.nastepny:=nil;
		teraz_znak^.txt:=znak;
		
		//Wczytujemy litery w wierszach az nie trafimy na koniec
		while znakchar(10) do
		begin
			read(znak);
			new(teraz_znak^.nastepny);
			teraz_znak:=teraz_znak^.nastepny;
			teraz_znak^.nastepny:=nil;
			teraz_znak^.txt:=znak;
		end
	end;

	//Wiersze
	while teraz  nil do
	begin
		tmp:=teraz;
		teraz_znak:=teraz^.txt;
			//Wypisujemy litery i caly czas sprzatamy po sobie.
			while teraz_znak  nil do
			begin
				write(teraz_znak^.txt);
				tmp_znak:=teraz_znak;
				teraz_znak:=teraz_znak^.nastepny;
				dispose(tmp_znak);
			end;
		teraz:=teraz^.nastepny;
		dispose(tmp);
	end
end.

Laboratorium programowania zad 5

Zadanie 5 z laboratorium programowania na Informatyce UW.

Zadanie 5 (termin wysylania rozwiazan: 15 II 2008, godz. 23:59)

(Komentarze)

Komentarze zaczynaja sie od pary znakow / i koncza na koncu wiersza.

Napisz program, ktory skopiuje plik tekstowy, wyrownujac wszystkie
komentarze tak, by zaczynaly sie w tej samej kolumnie. Komentarz,
ktorego poczatek jest najbardziej wysuniety w prawo, ma pozostac w
tym samym miejscu wiersza, a poczatki wszystkich, ktore zaczynaja
sie wczesniej, maja zostac przesuniete poprzez poprzedzenie ich
odpowiednia liczba spacji.

Program bedzie wywolywany z jednym parametrem - nazwa pliku tekstowego,
a wynikowy tekst wypisze na standardowe wyjscie.

Np. dla danych umieszczonych w pliku dane.txt:

wiersz pierwszy // to jest komentarz
drugi// to tez komentarz
tu nie ma komentarza
4 wiersz // ten komentarz zaczal sie od // a konczy tu

program wywolany poleceniem:

./zadanie5 dane.txt

powinien wypisac na wyjscie:

wiersz pierwszy // to jest komentarz
drugi           // to tez komentarz
tu nie ma komentarza
4 wiersz        // ten komentarz zaczal sie od // a konczy tu

Wskazowka:

Program powinien przejsc po pliku tekstowym dwa razy - raz, by poznac
pozycje najbardziej wysunietego komentarza i drugi raz, by stworzyc
kopie.

A oto rozwiązanie:

program zad5;
USES crt;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 5.


var
argumentow,dlugosc,i,j,najdluz:integer;
parametr,wiersz:string;
znaleziono:boolean;
plik:text;



begin

	//Przechwutujemy liczbe argumentow
	argumentow:=ParamCount();

	if (argumentow=1) then
	begin
		//Czytamy parametr
		parametr:=ParamStr(1);

		//Otwieramy plik
		assign(plik, parametr);
		reset(plik);
		najdluz:=0;
		while not EOF(plik) do
		begin
			//Wczytujemy po wierszu
			readln(plik,wiersz);
			dlugosc:=length(wiersz);
			i:=1;
			while ((inajdluz) then
						najdluz:=i;
					znaleziono:=true;
				end;
				i:=i+1;
			end;

		end;
		//wczytane. Teraz najdluz to pierwszy najdalej wysuniety / 

		//Przeskakujemy do poczatku.
		reset(plik);
				
		while not EOF(plik) do
		begin
			//Po wierszu
			readln(plik,wiersz);
			dlugosc:=length(wiersz);
			for i:=1 to dlugosc-1 do
			begin
				//Znalezlismy znak komentarza
				if ((wiersz[i]='/') AND (wiersz[i+1]='/')) then
				begin
					//Dodajemy spacje
					for j:=i to najdluz-1 do
					begin
						write(' ');
					end;
				end;
				//Piszemy znak
				write(wiersz[i]);
			end;
			//Piszemy ostatni znak z wiersza
			write(wiersz[i+1]);
			//I znak nowego wiersza.
			writeln();
		end;
		
	end
end.

Laboratorium programowania zad 4

Zadanie 4 z laboratorium programowania na Informatyce UW.

Zadanie 4 (termin wysylania rozwiazan: 8 II 2008, godz. 23:59)

(Samotnik)

Gra logiczna o nazwie Samotnik jest rozgrywana przez jedna osobe
na planszy, ktorej czesc pol zajmuja pionki.

Pojedynczy ruch polega na przeskoczeniu pionkiem pionka znajdujacego
sie na jednym z czterech sasiednich pol, zdjeciu przeskoczonego pionka
z planszy i umieszczeniu pionka, ktory przeskoczyl, bezposrednio
za polem przeskoczonym (wczesniej musi byc ono puste).

Np. ze stanu (kropka oznacza puste pole, gwiazdka to pionek):

**.

przejdziemy do:

..*

ze stanu:

.**

przejdziemy do:

*..

ze stanu:

.
*
*

przejdziemy do:

*
.
.


ze stanu:

*
*
.

przejdziemy do:

.
.
*

Napisz program, ktory dla zadanego stanu planszy S i wartosci n
wypisze wszystkie stany, z ktorych po n ruchach dojdziemy do
stanu S.

Postac danych:

Program jest wywolywany z jednym argumentem bedacym nieujemna
liczba calkowita, a ze standardowego wejscia wczytuje stan
planszy. Reprezentacja stanu sklada sie z siedmiu wierszy, kazdy
po siedem znakow. Znak kropki '.' reprezentuje puste pole
planszy, znak gwiazdki '*' reprezentuje pionka a znak spacji
reprezentuje miejsce poza plansza - tam pionek nigdy znalezc sie
nie moze.

Np. ciag znakow:

  ***  
  ***  
*******
***.***
*******
  ***  
  ***  

jest zapisem stanu poczatkowego Samotnika w jego klasycznej wersji.

Postac wyniku:

Program wypisuje na wyjscie wszystkie stany planszy, z ktorych
po n ruchach mozna osiagnac stan zadany na wejsciu. Kazdy stan
wypisujemy w takim formacie, w jakim byly dane na wejsciu (siedem
wierszy po siedem znakow). Dodatkowo, po kazdym stanie planszy
wypisujemy jeden pusty wiersz.

Np. dla danych postaci:

  ...  
  ...  
.......
...*...
.......
  ...  
  ...  

program wywolany poleceniem:

./rozwiazanie 1 < dane

powinien wypisac:

  ...  
  ...  
.......
.......
...*...
  .*.  
  ...  
    
  ...  
  .*.  
...*...
.......
.......
  ...  
  ...  
                
  ...  
  ...  
.......
....**.
.......
  ...  
  ...  
                        
  ...  
  ...  
.......
.**....
.......
  ...  
  ...  


Dla tych samych danych, program wywolany z argumentem 3 powinien
wypisac, miedzy innymi, stan:

  ...  
  ...  
...*...
.**....
.......
  .*.  
  ...  

Pelny wynik programu wywolanego z argumentem 3 jest zalacznikiem do
tresci zadania.

(Uwaga: Kolejnosc stanow wypisywanych na wyjscie nie musi byc taka,
jak w tym przykladzie, ale gdyby udalo sie Panstwu ja zachowac,
ulatwiloby mi to sprawdzanie rozwiazan.)

Mozna zalozyc, ze dane na wejsciu programu, oraz argument wywolania,
beda poprawne.

Wskazowka 1:

Zacznij od rozwiazania problemu cofniecia stanu planszy o jeden,
czyli do stanu bezposrednio poprzedzajacego zadany. Nastepnie
zastanow sie, jak zastosowac rekurencje do rozwiazania problemu
w wersji pelnej.

Wskazowka 2:

Liczbe argumentow, z ktorymi wywolano program, mozemy poznac wywolujac
funkcje ParamCount. Funcja ParamStr(i) zwroci nam i-ty argument
wywolania programu w postaci wartosci typu string.

Wartosc liczbowa reprezentowana przez wartosc typu string mozemy
obliczyc samodzielnie, lub skorzystac z procedury Val. Wywolanie
Val(s,x,w) umiesci na zmiennej x typu integer wartosc liczby, ktorej
ciag cyfr znajduje sie na zmiennej s typu string. Gdyby postac s
byla bledna, na zmiennej w typu word znajdzie sie kod bledu.

A oto rozwiązanie:

program zad3;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 4.

type
//plansza
plan=array [1..7,1..7] of char;

var start:plan;
argumentow,iteracji,i,j,blad:integer;
parametr,wiersz:string;


procedure wypisz(plansza:plan);
//Jak nietrudno sie domyslic, procedura wypisuje plansze
var i,j:integer;
begin
		for i:=1 to 7 do
		begin
			for j:=1 to 7 do
			begin
				write(plansza[i,j]);
			end;
			writeln();
		end;
		writeln();
end;



procedure ruch(plansza:plan;iteracja:integer);
//Rekurencyjna procedura. Wykonuje ruchy az iteracja spadnie do 0
var i,j:integer;
plansza2:plan;
begin

	//Doszlismy do odpowiedniej liczby ruchow
	if (iteracja=0) then
	begin
		wypisz(plansza);
	end
	else
	begin
		iteracja:=iteracja-1;
		//Idziemy po planszy. Dla kazdego pionka zaklada ze znalazl sie tam w wyniku ruchu
		for i:=1 to 7 do
		begin
			for j:=1 to 7 do
			begin
				//Mamy pionek
				if (plansza[i,j]='*') then
				begin
				
					//No i teraz zakladamy ze pionek znalazl sie tam w wyniku:
				
					//skok z dolu
					if ((i2) AND (plansza[i-1,j]='.') AND (plansza[i-2,j]='.')) then
					begin
						plansza2:=plansza;
						plansza2[i,j]:='.';
						plansza2[i-1,j]:='*';
						plansza2[i-2,j]:='*';
						ruch(plansza2,iteracja);
					end;
					
					//skok z prawej
					if ((j2) AND (plansza[i,j-1]='.') AND (plansza[i,j-2]='.')) then
					begin
						plansza2:=plansza;
						plansza2[i,j]:='.';
						plansza2[i,j-1]:='*';
						plansza2[i,j-2]:='*';
						ruch(plansza2,iteracja);
					end;					

				end
			end
		end
	end
	
end;







begin

	//Przechwutujemy liczbe argumentow
	argumentow:=ParamCount();

	if (argumentow=1) then
	begin
		//Czytamy parametr
		parametr:=ParamStr(1);
		Val(parametr,iteracji,blad);

		//Wczytujemy wejscie
		for i:=1 to 7 do
		begin
			readln(wiersz);
			for j:=1 to 7 do
			begin
				start[i,j]:=wiersz[j];
			end
		end;
		
		//wczytane.
		//Wywyolujemy
		ruch(start,iteracji);
	end
end.

Laboratorium programowania zad 3

Zadanie 3 z laboratorium programowania na Informatyce UW.

Zadanie 3 (termin wysylania rozwiazan: 1 II 2008, godz. 23:59)

(wyrazenia logiczne w ONP)

Dana jest gramatyka bezkontekstowa wyrazen logicznych w Odwrotnej
Notacji Polskiej (obok kazdej produkcji podano jej znaczenie):

E -> 0        falsz
E -> 1        prawda
E -> E E &    koniunkcja
E -> E E |    alternatywa
E -> E E =    rownowaznosc
E -> E E >    implikacja (pierwsze E implikuje drugie)
E -> E !      negacja

Napisz program, ktory wczyta z wejscia wyrazenie opisane powyzsza
gramatyka i wypisze na wyjscie 1 lub 0 w zaleznosci od tego, czy
wartoscia wyrazenia jest prawda czy falsz.

Dla danych niepoprawnych program powinien wypisac slowo BLAD.

Postac danych:

Na wejsciu znajdzie sie jeden wiersz tekstu zbudowanego ze znakow 0, 1,
&, |, =, >, ! i zakonczonego kropka. Pomiedzy kolejnymi znakami wyrazenia
nie bedzie spacji.

Postac wyniku:

Program wypisuje na wyjscie jeden wiersz z liczba 0 lub 1 albo ze
slowem BLAD.

Np. dla danych:

01>1!0|>110&&!=.

reprezentujacych wyrazenie logiczne:

((false => true) => ((not true) or false))  not (true and (true  and false))

program powinien wypisac:

0

A oto rozwiązanie:

program zad3;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 3.
var i,ile:integer;
wynik,blad:boolean;
zdanie:string;



function wczytaj:boolean;
//Funkcja wczytuje operator lub wartosc i decyduje co robic dalej.
var znak:char;
wynik,wynik1,wynik2:boolean;
begin
wynik:=false;

	if (blad=false) then
	begin
		//Jesli nie bylo bledu
		znak:=zdanie[i];
		i+=-1;

		//male zabezpieczenie jesli wykroczylismy poza zakres
		if i') then
			begin //Liczymy implikacje

			wynik1:=wczytaj();
			wynik2:=wczytaj();
			wynik:=NOT (wynik2 AND NOT wynik1);

			end
		else if (znak='!') then
			begin //Liczymy zaprzeczenie

			wynik1:=wczytaj();
			wynik:=NOT wynik1;

			end
		else //Podano znak spoza zakresu
			blad:=true;


	end;
wczytaj:=wynik;
end;





begin

	blad:=false;
	//Wczytujemy zdanie:
	readln(zdanie);
	ile:=length(zdanie);
	i:=ile;
	//Jesli zdanie ma jak powinno kropke na koncu:
	if (zdanie[ile]='.') then
		begin
			i+=-1;
			wynik:=wczytaj;
		end
	else //No jesli nie ma to blad
		blad:=true;


	//Teraz wypiszemy wynik

	//Jesli wystapil blad:
	if blad then
		writeln('BLAD')
	else
		if wynik then
			writeln('1')
		else
			writeln('0');


end.

Laboratorium programowania zad 2

Zadanie 2 z laboratorium programowania na Informatyce UW.

Zadanie 2 (termin wysylania rozwiazan: 25 I 2008, godz. 23:59)

(Liczby Fibonacciego)

Ciag liczb Fibonacciego jest okreslony nastepujaco:

* pierwsza liczba Fibonacciego jest 0
* druga liczba Fibonacciego jest 1
* liczba Fibonacciego o numerze N (wiekszym niz 2) jest suma liczb
  Fibonacciego o numerach N-1 i N-2

Oto kilkanascie poczatkowych wyrazow ciagu liczb Fibonacciego:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...

Napisz program, ktory wczyta z wejscia liczbe calkowita N i wypisze
na wyjscie, w kolejnych wierszach, N poczatkowych wyrazow ciagu liczb
Fibonacciego.

Program powinien wypisac liczby w zapisie pozycyjnym o podstawie 26
poslugujac sie malymi literami alfabetu lacinskiego jako cyframi.
Litera 'a' ma wiec reprezentowac cyfre 0, 'z' to 25. Cyfry nalezy
wypisywac w kolejnosci od najbardziej znaczacych.

Program nie moze zakladac, ze wartosc N bedzie na tyle mala, by liczby
Fibonacciego zmiescily sie w zakresie typow integer, longint itp.
Wolno jedynie zalozyc, ze liczby Fibonacciego, ktore program ma obliczyc,
nie beda mialy wiecej, niz 100 cyfr (w zapisie o podstawie 26).

Np. dla danej:

30

program powinien wypisac:

a
b
c
d
f
i
n
v
bi
cd
dl
fo
iz
on
xm
blz
cjl
dvk
gev
kaf
qfa
baff
bqkf
cqpk
egzp
gxoz
leoo
scdn
bdgsb
bvivo

Wskazowka:

W rozwiazaniu liczby nalezy reprezentowac jako ciagi cyfr w ukladzie
o podstawie 26, zapisane w tablicy.

A oto rozwiązanie:

program zad2;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 2.
type tablica=array [1..100] of char;
var n,i:integer;
//Tablice z liczbami
a,b,c : tablica;




procedure dodaj;
//Dodaje tablice a i b, w wsyniku dajac c. Operacja w ukladzie 26
var i,tmp_a,tmp_b,wynik,przeniesienie:integer;
begin
	przeniesienie:=0;
	//Liczby przedstawiamy od prawej strony tablicy.
	for i:=100 downto 1 do
	begin
		wynik:=0;
		tmp_a:=ord(a[i])-97;
		tmp_b:=ord(b[i])-97;
		wynik:=przeniesienie+tmp_a+tmp_b;
		c[i]:=char((wynik mod 26)+97);
		przeniesienie:=wynik div 26;
	end;
	
	//tutaj dodawanie powinno sie zakonczyc.
end;

procedure wypisz(t:tablica);
//Wypisuje tablice
var i:integer;
znak:char;
begin
	
	i:=2;
	znak:=t[1];
	//Pomijamy poczatkowe 0 - czyli a.
	
	while (znak='a') AND (i<101) do
	begin
		znak:=t[i];
		i+=1;
	end;
		
	i:=i-1;

	while i0 then
		writeln('a');

	if n>1 then
		writeln('b');
	
	for i:=3 to n do
	begin
		dodaj;
		wypisz(c);
		a:=b;
		b:=c;
	end;

end.

Lab Pascal zadanie 1

Zadanie 1 z laboratorium programowania na Informatyce UW.

 Zadanie 1 (termin wysylania rozwiazan: 18 I 2008, godz. 23:59)

(Lamiglowka "Pietnascie")

Dana jest plansza o rozmiarach cztery na cztery, na ktorej znajduje sie
pietnascie "klockow" oznaczonych duzymi literami. W pierwszym wierszu
planszy sa cztery klocki: "A", "B", "C" i "D", w drugim "E", "F", "G" i
"H", w trzecim "I", "J", "K", "L", w czwartym "M", "N", "O". Pole
w czwartym wierszu i czwartej kolumnie jest puste.

Klocek mozna przesunac na sasiadujace z nim wolne pole, zwalniajac tym
samym pole, na ktorym klocek znajdowal sie do tej pory.

W kazdej chwili na planszy jest co najwyzej jeden klocek, ktory mozna
przesunac w dol (ten, ktory znajduje sie nad pustym polem), co najwyzej
jeden, ktory mozna przesunac w prawo itd.

Napisz program, ktory umozliwi przesuwanie klockow na planszy i bedzie
wypisywal na wyjscie wynik.

Program wczyta z wejscia ciag liter ze zbioru {'l', 'p', 'g', 'd'}
zakonczony znakiem, ktory do tego zbioru nie nalezy. Kazda litera
jest poleceniem przesuniecia klocka na planszy:

'l' - w lewo
'p' - w prawo
'g' - w gore
'd' - w dol

Program wypisze na wyjscie stan poczatkowy planszy, a nastepnie dla kazdej
litery z wejscia bedzie probowal wykonac reprezentowane przez nia
przesuniecie klocka. Jesli przesuniecie nie bedzie mozliwe, bo np. puste
pole jest w ostatnim wierszu planszy, a wczytana litera to 'g', stan planszy
sie nie zmieni. Dla kazdej litery wczytanej z wejscia, niezaleznie od tego,
czy spowodowala ona przesuniecie klocka, wypisujemy wynikowy stan planszy.

Stan planszy wypisujemy w pieciu wierszach. W czterech pierwszych podajemy
znaki z klockow znajdujacych w kolejnych wierszach planszy, oznaczajac
spacja miejsce puste; piaty wiersz ma byc pusty.

Np. dla danych, znajdujacych sie w dolaczonym do tresci tego zadania pliku
zsi07z01.dane, program powinien wypisac to, co jest w pliku zsi07z01.wynik.

I oto rozwiązanie:

Sieci komputerowe zadanie

Zadanie zaliczeniowe z Sieci Komputerowych

Oto treść:

Zadanie zaliczeniowe z Laboratorium z Sieci Komputerowych 2007

Należy napisać program filtrujacy strumień pakietów wywoływany z pięcioma argumentami:
- nazwš wej?ciowego pliku zawierajšcego pakiety (zrzut tcpdump),
- nazwš pliku wyj?ciowego, do którego należy zapisać wszystkie przepuszczone pakiety,
- nazwš pliku wyj?ciowego z informacjami na temat przepuszczanych i odrzuconych pakietów,
- nazwš pliku z "czarnš" listš adresów ip,
- nazwš pliku z "białš" listš adresów ip i portów TCP,
    nazwa_programu plik_in plik_out plik_admin plik_bad plik_good

Plik plik_bad ma następujšcy format. W kolejnych linijkach umieszczone sš:
    adres_ip niepusty_cišg_białych_znaków kierunek
gdzie kierunek jest jednym ze słów SRC lub DEST okre?lajšcymi czy chodzi o ?ródłowy czy docelowy adres ip.

Plik plik_good ma następujšcy format. W kolejnych linijkach umieszczone sš:
    adres_ip niepusty_cišg_białych_znaków kierunek niepusty_cišg_białych_znaków port_begin,port_end
gdzie:
    - kierunek jest jednym ze słów SRC lub DEST okre?lajšcymi czy chodzi o ?ródłowy czy docelowy adres ip,
    - port_begin,port_end oznaczajš zakres portów (okre?lony tylko dla protokołów TCP i UDP)
    ?ródłowych lub docelowych (w zależno?ci od parametru kierunek).

Każdy pakiet należy poddać analizie. Pakiet odrzucamy jeżeli spełniony jest przynajmniej jeden z warunków:
1) ?ródłowy lub docelowy adres ip znajduje się w plik_bad i zgadza się kierunek przesyłu danych,
2) pakiet jest wysyłany za pomocš protokołu TCP lub UDP i jego ?ródłowy lub docelowy adres ip
    znajduje się w plik_good, ale numer portu nie należy do podanego zakresu,
3) pakiet jest wysyłany za pomocš protokołu TCP, ale nie dane w nim zawarte nie pasujš do następujšcego formatu:
    pierwszym znakiem jest cyfra od 1 do 9 mówišca ile razy powinny być w danym pakiecie powtórzone dane,
    na przykład:
        2_tresc_tresc
        3_tresc_tresc_tresc
        7_tresc_tresc_tresc_tresc_tresc_tresc_tresc
W przypadku odrzucenia pakietu należy wpisać nowš linię do plik_admin w następujšcym formacie:
    ip_nadawcy ip_odbiorcy nazwa_protokołu komunikat
przy czym komunikat jest jednym spo?ród:
    - BAD SRC/DEST IP
        w przypadku niespełnienia warunku 1,
    - BAD SRC/DEST PORT
        w przypadku niespełnienia warunku 2,
    - BAD PACKET FORMAT, MISSING NUMBER
      BAD PACKET FORMAT, NOT MATCHING DATA
        w przypadku niespełnienia warunku 3 z powodu odpowiednio braku cyfry na poczštku lub braku pasujšcych danych.

Pozostałe pakiety należy przepu?cić wpisujšc do plik_out oraz wpisać nowš linię do plik_admin w następujšcym formacie:
    ip_nadawcy ip_odbiorcy nazwa_protokołu PACKET OK

Program należy przesłać na adres mailowy prowadzšcego grupę ćwiczeniowš:
    piotr.sawicki@mimuw.edu.pl
    michal.bernardelli@mimuw.edu.pl
do 2 grudnia 2007 roku do godziny 23:59.
Ocena rozwišzań wysłanych po tym terminie (wliczajšc w to sesję poprawkowš) będzie obniżona o jeden stopień.
Program powinien być skompresowany wraz z zaprojektowanym przez siebie kompletem testów.
Nazwa spakowanego pliku powinna być taka sama jak wydziałowy login.
Program ma się kompilować i działać na komputerach w laboratorium komputerowym MIM.
Za brak lub niewystarczajšcš liczbę komentarzy w kodzie ?ródłowym programu będzie obniżana ocena.
Na ostatnich ćwiczeniach należy przyj?ć i zaprezentować działanie swojego programu.

A oto rozwiazanie:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 



/* default snap length (maximum bytes per packet to capture) */
#define SNAP_LEN 1518

/* ethernet headers are always exactly 14 bytes [1] */
#define SIZE_ETHERNET 14

/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN	6

pcap_dumper_t *plik;

/* Ethernet header */

struct sniff_ethernet {
        u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
        u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
        u_short ether_type;                     /* IP? ARP? RARP? etc */
};

/* IP header */
struct sniff_ip {
        u_char  ip_vhl;                 /* version <> 2 */
        u_char  ip_tos;                 /* type of service */
        u_short ip_len;                 /* total length */
        u_short ip_id;                  /* identification */
        u_short ip_off;                 /* fragment offset field */
        #define IP_RF 0x8000            /* reserved fragment flag */
        #define IP_DF 0x4000            /* dont fragment flag */
        #define IP_MF 0x2000            /* more fragments flag */
        #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
        u_char  ip_ttl;                 /* time to live */
        u_char  ip_p;                   /* protocol */
        u_short ip_sum;                 /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
};

#define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)                (((ip)->ip_vhl) >> 4)

/* TCP header */
typedef u_int tcp_seq;

struct sniff_tcp {
        u_short th_sport;               /* source port */
        u_short th_dport;               /* destination port */
        tcp_seq th_seq;                 /* sequence number */
        tcp_seq th_ack;                 /* acknowledgement number */
        u_char  th_offx2;               /* data offset, rsvd */
	#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
        u_char  th_flags;
        #define TH_FIN  0x01
        #define TH_SYN  0x02
        #define TH_RST  0x04
        #define TH_PUSH 0x08
        #define TH_ACK  0x10
        #define TH_URG  0x20
        #define TH_ECE  0x40
        #define TH_CWR  0x80
        #define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
        u_short th_win;                 /* window */
        u_short th_sum;                 /* checksum */
        u_short th_urp;                 /* urgent pointer */
};

struct sniff_udp {
        u_short uh_sport;               /* source port */
        u_short uh_dport;               /* destination port */
        u_short uh_length;				/*length header+data*/
        u_short uh_checksum;            /* chechsum */
      
};

//Struktura listy white i black

typedef struct Adresy {
	char Adres[15];
	char kierunek[4];
	int port_start;
	int port_stop;
	struct Adresy * nastepny;
};

//plik admin
FILE *admin;
struct Adresy *biala;
struct Adresy *czarna;

//funkcje operujace na listach black i white.

struct Adresy * wczytaj_adresy(char* plik,int porty)
{//wczytuje adresy z pliku i zwraca wskaznik do listy.
	FILE *f;
	struct Adresy *start;
	struct Adresy *teraz;
	int wynik;
	char ciag[128];
	char * tmp;
	char znak;

	f=fopen(plik,"r");
	wynik=fscanf(f,"%15s",ciag);



	if(wynik!=EOF)
	{
		start=malloc(sizeof(struct Adresy));
		start->nastepny=NULL;
		start->port_start=0;
		start->port_stop=0;

		strcpy(start->Adres,ciag);

		//powinno wczytac spacje:
		wynik=fscanf(f,"(space)");

		//powinno wczytac src lub dest
		wynik=fscanf(f,"%4s",ciag);

		
		if(strcmp(ciag,"SRC")||strcmp(ciag,"DEST"))
		{
			strcpy(start->kierunek,ciag);
		}
		
		//jesli mamy tez czytac numery portow.
		if (porty==1)
		{
			wynik=fscanf(f,"(space)");
			//przeczytalismy puste znaki
			wynik=fscanf(f,"%s,",ciag);
			//wczytalismy porty. Rozbijemy je.
			tmp = strtok (ciag,",");
			start->port_start=atoi(tmp);
			tmp = strtok (NULL, ",");
			start->port_stop=atoi(tmp);
		}

		while(znak!='n')
		{
			//czytamy wszystko do konca linii.
			wynik=fscanf(f,"%c",&znak);
		}

		teraz=start;
		wynik=fscanf(f,"%s",ciag);

		while(wynik!=EOF)
		{
			teraz->nastepny=malloc(sizeof(struct Adresy));
			teraz=teraz->nastepny;
			teraz->nastepny=NULL;
			teraz->port_start=0;
			teraz->port_stop=0;
			strcpy(teraz->Adres,ciag);

			//powinno wczytac spacje:
			wynik=fscanf(f,"(space)");

			//powinno wczytac src lub dest
			wynik=fscanf(f,"%s",ciag);

			if((strcmp(ciag,"SRC"))||(strcmp(ciag,"DEST")))
			{
				strcpy(teraz->kierunek,ciag);
			}
			
			//jesli mamy tez czytac numery portow.
			//jesli mamy tez czytac numery portow.
			if (porty==1)
			{
				wynik=fscanf(f,"(space)");
				//przeczytalismy puste znaki
				wynik=fscanf(f,"%s,",ciag);
				//wczytalismy porty. Rozbijemy je.
				tmp = strtok (ciag,",");
				teraz->port_start=atoi(tmp);
				tmp = strtok (NULL, ",");
				teraz->port_stop=atoi(tmp);
			}

			while(znak!='n')
			{
				//czytamy wszystko do konca linii.
				wynik=fscanf(f,"%c",&znak);
			}

			wynik=fscanf(f,"%s",ciag);
		}

		return start;
	}
	else
	{
		return NULL;
		//blad. plik pusty albo co.
	}
	fclose(f);
}


int lista(struct Adresy * lista,char* source,char* destination, int port_zrodlo,int port_docelowy)
{
	//zwraca 1 jesli zrodlowy lub docelowy ip sa na liscie.
	//+1 jesli kierunek sie zgadza
	//+2 jesli port sie zgadza.
	//0 jesli adresu nie ma.
	int zwroc,naj_zwroc;
	struct Adresy *teraz;
	teraz=lista;
	zwroc=0;
	naj_zwroc=0;

	//szukamy
	while ((teraz!=NULL)&&(zwrocAdres,source)==0)||(strcmp(teraz->Adres,destination)==0))
		{
			if(zwroc==0)
			{
				//ip jest na liscie
				zwroc=1;
				
			}

			if((zwroc==1)&&(((strcmp(teraz->Adres,source)==0)&&(strcmp(teraz->kierunek,"SRC")==0))||((strcmp(teraz->Adres,destination)==0)&&(strcmp(teraz->kierunek,"DEST")==0))))
			{
				//odkrylismy wlasnie wpis w ktorym kierunek sie zgadza.
				zwroc=zwroc+1;
			}

			if(((port_zrodlo!=0)||(port_docelowy!=0))&&((zwroc==1)||(zwroc==2))&&(((strcmp(teraz->kierunek,"DEST")==0)&&(port_docelowy>=teraz->port_start)&&(port_docelowyport_stop))||((strcmp(teraz->kierunek,"SRC")==0)&&(port_zrodlo>=teraz->port_start)&&(port_zrodloport_stop))))
			{
				//Odkrylismy wlasnie ze i port sie zgadza.
				zwroc=zwroc+2;
			}

		}
		
		if(zwroc>naj_zwroc)
		{
			naj_zwroc=zwroc;
		}
		
		teraz=teraz->nastepny;
	}

	return naj_zwroc;
}

int posprzataj(struct Adresy * lista)
{
	struct Adresy* tmp;
	
	while(lista!=NULL)
	{
		tmp=lista;
		lista=lista->nastepny;
		free(tmp);
	}
	
	return 0;
}

//zapisuje do pliku admin.
int zapisz(char *source,char *destination,char *prot,char *komunikat)
{
	fprintf(admin,"%s %s %s %sn",source,destination,prot,komunikat);
}

//Funkcje zwiazane z wlasciwa analiza.


void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);



int check_payload(const u_char *payload, int len)
{
	int dlugosc,i,j;

	if((payload[0]'9'))
	{
		//liczba ma byc z przedzialu 0-9
		return 1;
	}
	else
	{
		dlugosc=(len-1)/(payload[0]-48);
		j=1;
		for(i=dlugosc+1;idlugosc)
			{
				j=1;
			}
		}
	}
	
	return 0;
}



/*
 * dissect/print packet
 */

void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
	/* declare pointers to packet headers */
	const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
	const struct sniff_ip *ip;              /* The IP header */
	const struct sniff_tcp *tcp;            /* The TCP header */
	//const struct sniff_udp *udp;			/* The UDP header */
	const char *payload;                    /* Packet payload */
	char *source,*destination;
	char prot[10];						//nazwa protokolu

	int size_ip;
	int size_tcp;
	int size_payload;
	int wynik_biala,wynik_czarna,port_zrodlowy,port_docelowy,wynik_payload;
	
	/* define ethernet header */
	ethernet = (struct sniff_ethernet*)(packet);
	/* define/compute ip header offset */
	ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
	size_ip = IP_HL(ip)*4;
	if (size_ip ip_p) {
		case IPPROTO_TCP:
			strncpy(prot,"TCP",4);
			break;
		case IPPROTO_UDP:
			strncpy(prot,"UDP",4);
			break;
		case IPPROTO_ICMP:
			strncpy(prot,"ICMP",5);
			break;
		case IPPROTO_IP:
			strncpy(prot,"IP",3);
			break;
		default:
			strncpy(prot,"OTHER",6);
			break;
	}


	//Rozpoznajemy adresy zrodlowy i docelowy
	destination=inet_ntoa(ip->ip_src);
	source=(char*)malloc(sizeof(char)*strlen(destination));
	strncpy(source,destination,strlen(destination));
	source[strlen(destination)]='';
	destination=inet_ntoa(ip->ip_dst);
	
	//testujemy.
	wynik_czarna=lista(czarna,source,destination,0,0);
	
	if(wynik_czarna>1)
	{
		//odrzucamy z powodu warunku 1 - jest w pliku_bad
		zapisz(source,destination,prot,"BAD SRC/DEST IP");
	}
	else
	{
		if (ip->ip_p==IPPROTO_TCP || ip->ip_p==IPPROTO_UDP) //tcp lub udp
		{
			tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
			port_zrodlowy=ntohs(tcp->th_sport);
			port_docelowy=ntohs(tcp->th_dport);
			//testujemy.
			wynik_biala=lista(biala,source,destination,port_zrodlowy,port_docelowy);
			
			if((wynik_biala==1)||(wynik_biala==2)) //jest na liscie, ale nie zgadza sie port. (jesli by sie zgadzal byloby 3 albo 4)
			{
				//odrzucamy z powodu niespelnienia warunku 2.
				zapisz(source,destination,prot,"BAD SRC/DEST PORT");
			}
			else
			{
				//ok. przeszlismy pierwsze dwa testy. teraz czy format pliku sie zgadza.
				wynik_payload=0;
				
				if (ip->ip_p==IPPROTO_TCP)
				{
					size_tcp = TH_OFF(tcp)*4;
					if (size_tcp ip_len) - (size_ip + size_tcp);
					
					if (size_payload > 0) 
					{
						wynik_payload=check_payload(payload,size_payload);
						//if(wynik_payload==2)
						//	printf("%snnnn---------n",payload);
						
					}
				}
				
				if(wynik_payload==1)
				{
					zapisz(source,destination,prot,"BAD PACKET FORMAT, MISSING NUMBER");
				}
				else if (wynik_payload==2)
				{
					zapisz(source,destination,prot,"BAD PACKET FORMAT, NOT MATCHING DATA");
				}
				else
				{
					//PAKIET OK!!
					pcap_dump(plik, header, packet);//przepuszaczamy
					zapisz(source,destination,prot,"PACKET OK");
				}
			}
		}
		
	}
	
	return;
}




/*main-----------------------------------------------------------------*/
/*main-----------------------------------------------------------------*/
/*main-----------------------------------------------------------------*/
int main(int argc, char **argv)
{
	//char *dev = NULL;			/* capture device name */
	char errbuf[PCAP_ERRBUF_SIZE];		/* error buffer */
	pcap_t *handle;				/* packet capture handle */

	if(argc==6)
	{

		//wczytujemy dane z odpowiednich list.
		czarna=wczytaj_adresy(argv[4],0);
		biala=wczytaj_adresy(argv[5],1);

	  	if (!(handle=pcap_open_offline(argv[1], errbuf)))
		 {
			perror(errbuf);
			exit(1);
		 }

	  	if (!(plik=pcap_dump_open(handle, argv[2])))
		 {
			printf("BLADn");
			exit(1);
		 }
		
		admin=fopen(argv[3],"w");

		if (pcap_dispatch(handle, -1/*num_packets*/, got_packet,(u_char *) admin));

		fclose(admin);
		pcap_dump_close(plik);
		pcap_close(handle);
		//sprzatamy pamiec:
		posprzataj(biala);
		posprzataj(czarna);
		
	}
	else
	{
		printf("Podaj 5 parametrow!!n");
		return 1;
	}
	return 0;
}