/*	Néhány egyszerűbb feladat			*/
/*							*/
/*JAVASLAT: Lehetőleg önállóan próbálja megoldani 	*/
/* a kitűzött feladatokat, csak akkor 			*/
/* forduljon segítséghez, vagyis akkor nézze meg	*/
/* az útmutatót, ha sehogy sem boldogul.		*/											


/*JÓTANÁCSOK:

1. A fent leírtak csak segíthetik az önálló tanulást, de nem elegendőek a tudáshoz,
főleg pedig nem pótolhatják az önálló feladatmegoldást.
Valószínűleg az itt leírtak alapos áttanulmányozásához sem elég pár óra, de lehet, hogy egyetlen éjsza sem, az önálló feladatmegoldáshoz viszont még több idő kell. Ne sajnálja rá az időt, ha eredményes akar lenni.

2. Kövesse a fent leírt utasításokat is, vagyis darabonként is próbáljon ki egy-egy eljárást. Ezt a módszert egyébként is célszerű megszokni, vagyis amikor önállóan old meg feladatokat, akkor is próbálja ki részleteiben is az egyes eljárásokat.

3. Ha elakad, vagy csak nem igazán érti, hogy mit is csinál egy jól működő eljárás, kapcsolja be a trace-t. (Lehet a grafikusat is, az látványosabb, de a sima numerikus is sokat segít.)

4. Olvasgassa a help-et!

5. Konkrét javaslat a fent leírtakhoz:
A fenti szövegben szabályok és magyarázatok váltják egymást, emiatt az egy feladatmegoldáshoz tartozó szabályok között esetleg sok egyéb sor is van. Javaslom, hogy rakja külön fájlba az egy-egy megoldáshoz tartozó szabályokat, és így is próbálja meg lefuttatni. Fontos, hogy együtt is lássa az összetartozó szabályokat. Figyelem! Egy szabály több feladatmegoldáshoz is tartozhat, vagyis több önálló fájlba is átkerülhet.
*/





/*1. Állapítsuk meg két szám legnagyobb közös osztóját!

Matematikai ismeret: 
a/ két szám közös osztója osztója a két szám különbségének is.
b/ ha a nagyobb szám és a kisebb szám hányadosának maradékával elosztjuk a kisebb számot, majd a kapott maradékkal az előző maradékot, stb,. akkor előbb utóbb 0 lesz a maradék. Ennek az osztásnak a nevezője (vagyis az utolsó 0-tól különböző maradék) lesz a legnagyobb közös osztó

JAVASLAT: Az eddigi segítség alapján próbálja meg önállóan kitalálni.
*/


































/*  ha mégsem megy:

a/ változat: 
*/

lnko1(A,A,A).
lnko1(A,B,C) :- A>B,D is A-B,lnko1(B,D,C).
lnko1(A,B,C) :- B>A,D is B-A,lnko1(A,D,C).

	/*A nagyobbik és kisebbik szám különbségét (D) képezzük, és evvel,
	valamint a kisebbik számmal folytatjuk az eljárást.
	Az eredményt a harmadik paraméter tartalmazza.
	Az eljárás akkor áll le, ha a vizsgált két szám egyenlővé válik. Ekkor az
	eredmény is ugyanez a szám.

	Próbálja ki, pl.: lnko1(15,12,X).
	*/



/* b/ változat:
*/

lnko2(A,0,A).
lnko2(A,B,C) :- A>0,B>0, Z is A mod B,lnko2(B,Z,C).

	/*Mivel a kisebb és a nagyobb szám osztásának maradéka a 	kisebb 	szám lesz, ezért nem kell vizsgálni, hogy A és B közül melyik a
	nagyobb, hiszen a második lépésben úgyis a kisebb kerül a második
	paraméter helyére.
	Az eredmény a harmadik paraméter helyén keletkezik.
	Képezzük tehát a két szám maradékát, és evvel folytatjuk az algoritmust.
	Akkor állunk meg, ha nincs maradék. Ekkor az eredmény maga az 
	osztandó.

	Próbálja ki. Ha nem érti, kérjen nyomkövetést!
	*/



/*Indító eljárásba ágyazva (csak az egyiket, a másik ugyanilyen):
*/

start1:-writeln('Kérem a két számot!'), write('A= '),read(A), write('B= '),read(B),
	lnko1(A,B,C), write('A legnagyobb közös többszörös: '), write(C).
	

	/******************************************************/





/*2.  Döntsük el egy számról, hogy prímszám-e vagy sem. Ha nem az, irassuk ki az osztóit is!
*/

/*Ötlet:
Egy szám akkor prím, ha nincs valódi osztója. Vagyis célszerű lenne előbb azt megvizsgálni, hogy egy számnak van-e valódi osztója, azaz egy olyan eljárást írni, amelyik ezt vizsgálja. Egy szám akkor prím, ha nem teljesül rá az előbb említett szabály.
Külön megírhatja azt a szabályt is, amely meghatározza egy szám összes osztóját, 
majd végül rakja össze az alkalmazható szabályokat.


JAVASLAT: Saját érdekében csak akkor nézze meg a megoldást, ha végképp nem boldogul a kiirt feladattal!!!

*/















































/*Biztos, hogy nem boldogul vele? Ne legyen túl lusta!
*/



















































/* egy megoldási javaslat
*/


%% oszthatóságvizsgálat
       

 oszthato(X,N):- M is N+1, M < sqrt(X), X mod M =\= 0, oszthato(X,M).
 oszthato(X,N):- M is N+1, X mod M =:= 0.
 
	/*Azt vizsgáljuk, hogy osztható-e X 2-vel, 3-mal, 4-gyel, stb.
	A fent megírt szabály az általános esetet vizsgálja, vagyis az N-edik 
	utánit. Ha nem osztható M-mel, akkor folytassa az eljárást,
	ha osztható, akkor álljon meg.
	Figyelni kell arra is, hogy ne okozzunk végtelen ciklust. Jelenleg ez
	a M < sqrt(X) feltételvizsgálat nélkül sem fordulna elő, hiszen ha M 	értéke 
	pontosan X lenne, akkor nem teljesülne az első feltétel, és leállna. 
	Fölösleges azonban addig elmenni, hiszen ha gyok(X)-ig nincs 
	osztó, akkor utána sincs.

	Próbálja ki önállóan is! (gyok(X)-nél nagyobb N-re rosszul működik,
	mert a második szabályban nincs benne a M < sqrt(X) feltételvizsgálat.
	Az eredeti feladat szempontjából azonban ez lényegtelen.

	Figyelje meg, hogy ez az eljáras "no"-val is végződhet, hiszen pont az a
	kérdés, hogy egy állítás teljesül-e vagy sem.

	Nézze meg a help-ben a szabályban szereplő műveleti-jelek pontos
	jelentését!
	*/

/* Ezek után egy szám prím, ha 1-ről indulva nem találunk hozzá egyetlen osztót sem:
*/

prim(X):-not(oszthato(X,1)).



%% Egy szám összes osztójának kiiratása:


osztok(X,M):- M =< X, X mod M =:= 0, writeln(M), M1 is M + 1, osztok(X,M1).
osztok(X,M):-M=<X, M1 is M + 1,osztok(X,M1).
osztok(_,_).
  
	/*Ha X osztható M-mel, akkor írja ki M értékét, majd folytassa az eljárást 
	a következő számmal (M+1-gyel). 
	Akkor is folytassa az eljárást a következő számmal, ha X nem osztható 
	M-mel (vagyis egyébként, ezért nem kell ezt külön leírni a második 
	szabályban), de ekkor ne írjon ki semmit.
	Mindezt csak addig csinálja, amig el nem értük az X-et.
	Ha elértük, álljon le. Ekkor azonban lényegtelen, hogy mennyi M,X
	 értéke, ezért elég aláhúzással jelezni.

	Megjegyzés: Ez egy klasszikus példa a végrekurziós ciklusszervezésre.
	Ugyanígy lehet megoldani egy sereg egyéb feladatot:
	Amig a ciklusváltozó értéke kisebb mint a végérték, csinálja a következőt:
	Ha teljesül valamilyen feltétel a ciklusváltozóra, akkor végezze el a feltételtől
 	függő műveletet és folytassa az eljárást a ciklusváltozó következő értékére.
	Egyébként is folytassa az eljárást, de ne tegyen semmit (vagy esetleg egy más
 	feltételtől függő dolgot).

	A ciklusszervezés még egyszerűbb esete (nincs semmi feltétel):
	Amig a ciklusváltozó értéke kisebb mint a végérték, csináljon valamit,
	majd folytassa az eljárást a ciklusváltozó új értékével.
	
	Minden esetben rendelkeznünk kell arról is, mi történjen, ha a 
	ciklusváltozó elérte a végértéket.
	*/


%%  inditás 
 
start2:-write('Melyik szamra kivancsi: '),read(Szam), kiir(Szam).
         
	/* A szám beolvasása után döntés elé kerülünk: másképp kell 
	"viselkednünk", ha prímszámot vagy nem prímszámot olvastunk be.
	Ha kicsit is "bonyolultabb" döntés elé kerülünk, akkor célszerű külön 
	foglalkozni vele, vagyis célszerű külön eljárást írni a kérdés 
	megoldására. Ezt szolgálja a kiir.
	Természetesen ahhoz, hogy működni tudjon, a kiir eljárásnak szüksége
 	van a beolvasott Szam-ra.
	*/

  
  kiir(X):-prim(X),write('\nA szam prim.').
  kiir(X):-writeln('\nA szam nem prim. Osztoi: '), osztok(X,1).



	/***********************************************************/



/* 3. Anna és Béla a következő játékot játssza: 
 Felváltva mondanak egy 1 és 10 közötti számot. A játék addig tart, amíg a mondott számok összege el nem ér egy előre beolvasott értéket. Az nyer, akinél ez az osszeg először éri el vagy lépi túl az adott korlátot. 
Szimulálja a játékot Prologban!
*/


/* Tudom, hogy nagy a kísértés, de próbálja meg előbb önállóan megcsinálni!
*/

















































/* Természetesen a feladat többféle módon is megoldható.
Most egy variációhoz adok ötletet.

Két dolgot kell megoldani:
  1. biztosítani, hogy felváltva léphessenek
  2. számon tartani, hogy mekkora az eddigi összeg, és figyelni, hogy túllépte-e a korlátot.
     
A váltakozás megoldására az előjelváltás tűnik ügyes megoldásnak. Emiatt +1 jelzi majd, hogy 
Anna kovetkezik, -1, hogy Bela.  


Próbálja meg az ötlet segítségével 

*/














































/* Biztos, hogy nem megy? Gondolkozzon még egy kicsit!
*/
















































/* Biztos, hogy eleget gondolkodott?
*/

  













































/*Na, jó!
Az ígért megoldás:
*/


  %% kiiratjuk a következő játékos nevét  
  

 kerdez(1):-write('Anna: ').
 kerdez(-1):-write('Bela: ').   


/* a soronkövetkezőtől (Ki) megkérdezzük a számát(X) (csak 0 és 10 között lehet), kiszámoljuk az új  összeget, megvizsgáljuk, hogy folytatódhat-e a játék. Ha igen, akkor meghatározzuk a következő játékost és folytatjuk.
Ha nem, kiirjuk a győztest.  */
  

jatek(S,Ki,H) :- kerdez(Ki),be(X),
                  UjS is S + X, UjS < H, 
                  UjKi is -Ki, jatek(UjS,UjKi,H).
jatek(_,1,_):- write('gyoztes: '), write('Anna').
jatek(_,-1,_):- write('gyoztes: '),write('Bela').

	/*paraméterezés:
	éppen aktuális összeg, soronkövetkező játékos sorszáma, a beolvasott 	korlát.
	*/


be(X):-read(X),0<X,X<10,!.
be(X):-write('hibas szam, ujra! '),be(X).
	
	/* megvizsgáljuk, hogy a beolvasott szám 0 és 10
	közé esik-e, ha nem, megismételjük a beolvasást. */



    %% inditas  

start3:- write('Meddig játszotok: '),read(H), jatek(0,1,H).      
        


/*

Egy másik lehetséges megoldás (beküldött hallgatói megoldás)
*/


start4:- write('Meddig számoljak? '), read(N), 
		jatek(N,0).

jatek(N,Eddig):-(
				N>Eddig,
			    write('\n Anna mond egy számot(1-10 között): '),read(Szam),
				UjEddig is Eddig+Szam,
				(
				UjEddig>=N,
					write('\n Anna nyert'),
					jatek(N,UjEddig)
				;
					write('\n Béla mond egy számot(1-10 között): '),read(Szam2),
					UjUjEddig is UjEddig+Szam2,
					(
					UjUjEddig>=N,
						write('\n Béla nyert'),
						jatek(N,UjUjEddig)
					;
						jatek(N,UjUjEddig)
					)
				)
				;
				write('Vége')
				).


