[ reiser @ 21.11.2004. 21:32 ] @
Imam jednu funkciju, koju pozivam sa parametrom n, tipa integer.
Kako da napravim da ta funkcija napravi n brojaca ugnjezdena jedan u drugi ? Primer :

Code:

For C1 := 0 to 9 Do
Begin
  // Do something
  For C2 := 0 to 9 Do
  Begin
  // Do something
    For C3 := 0 to 9 Do
    Begin
    // Do something
    End;
  End;
End;

Znaci ovaj kod gore bi zavrsio posao, ali meni treba jedna univerzalna funkcija koja moze kreirati proizvoljan broj brojaca...

poz
[ bancika @ 21.11.2004. 22:21 ] @
tebi trebaju varijacije n elementata sa ponavljanjem. ideja je sledeca:
imas ugnjezdene petlje
Code:

for a1 := d1 to g1 do
 ...
  for an := dn to gn do

napravi niz duzine n i posavi a[i]=d[i], za svako i
onda radis sledece

repeat

//obrada, indeksi su u nizu a[i]

j := n;
while (j > 0) and (a[j] = g[j]) do
 begin
  a[j] := d[j]; Dec(j);
 end;
if j > 0 then
 Inc(a[j]);
until j = 0;


mislim da je ok, samo kucam ti iz glave, pa nisam siguran bas 100% :)
[ filjo @ 21.11.2004. 22:29 ] @
Ma znao sam da ces na kraju doci do ovog problema.
Ovako stoje stvari:

n - broj brojaca tj. broj petlji.
mn - od kojeg broja pocinje brojanje npr. 0
mx - na kojem broju se zavrsava npr. 9

u br[x] vidis trenutno stanje brojaca;

Sve je ovo super, ako ti izmedju svake for petlje nemas kod, vec su one ugnezdene jedna u drugu, a kod se izvrsava tek u zadnjoj. To je onda ovaj slucaj.

Ako hoces da se izmedju svake petlje izvrsi neki tvoj kod, onda moras uz brojace da imas i pokazivace na funkcije koje se izvrsavaju. Znaci koliko brojaca, toliko pokazivaca na funkcije, ali to je vec druga prica.

Code:

nekafunkcija ili procedura

var i,n,mn,mx:integer;
  br:array[1..100] of integer;

  function povecaj(x:integer):boolean;
  begin
    br[x]:=succ(br[x]);
      if br[x]>mx then
        begin
          if x=1 then
            povecaj:=true
          else
            begin
              br[x]:=mn;
              povecaj:=povecaj(x-1);
            end;
        end
      else
        povecaj:=false;
  end;

begin
  n:=3;
  mx:=9;
  mn:=0;
  for i:= 1 to n do br[i]:=mn;
  while not povecaj(n) do
    begin
        // ovde ide kod
    end;
end;


[ milika @ 22.11.2004. 13:44 ] @
Ovo je jedino moguce uz pomoc rekurzije i pokazivaca na procedure
ali to bas nije osnovni paskal...

vidi ti bolje da li mozes osnovnu ideju da uprostis...
pozdrav.,..
[ broker @ 22.11.2004. 14:30 ] @
Ako uzmemo da gornji primer znaci da parametar odredjuje koliko je ugnjezdenih petlji a da saka petlaj uvek broji od 0 do 9 to dosta pojednostavljujes stvar.

Da uprostimo, petlej se vrte ali samo ona najdublja stvarno zivrsava neki kod:

Onda ti ustvari treba jedna petlja koja ce brojati od 0 do m gde je m = 10 na n-ti a n ulazni parametar. U toj petlji radi sta treba.

E sad da se vratimo na komplikovaniji slucaj da svaka petlja treba da radi jos nesto osim sto vrti petlju unutar sebe kao sto si ti naveo u primeru.

U tom slucaju opet radi ista petlja samo sto sad u nju treba da stavis malo uslova da proveris stanje brojaca i da na osnovu toga izvrsavas odredjeni kod.

Nego da razjasnim sustinu. S obzirom da ti svaka petlja vrti od 0 do deset to znaci da ako neka cifra u vrednosti brojaca m jednaka nulit to znaci da na tom nivou treba zivrsiti predvidjeni kod. Da imas fiksanbrojpetlji mogao bi sa mod da utvrdjujes vrdnsoti cifara ali posto nije, trenutno mi pada na pamet da pretvoris m u string i dopunis sa nulama ispred tako da dobijeni string ima onoliko znakova koliko ima petlji pa da onda proveravas koje su cifre '0' i da izvrsavas odgovarajuci kod.

Naravno, uvek mozes da napravis niz od n integer-a da ti sluze kao brojaci pa da ih rucno uvecevas u svakoj iteraciji ali s obzirom da ti pelje broje od 0 do 9 onda mozes da iskorsitis obican dekadni sistem jedne integer vrednosti. Svaka cifra ti predstavlja jedan brojac.

Nekako mi se vise svidja ovakvo resenje nego petljanje sa rekurzijom, koje bi bilo komplikovano zbog potrebe da se izvrsava razlicit kod u svakoj petlji.


[ -zombie- @ 23.11.2004. 09:45 ] @
o bože.. "petljanje sa rekurzijom"??

pa ovo je školski primer za upotrebu rekurzije..

(a usput, ovaj, to što je broker opisao, to neće, ovaj neće nikad da.. poleti..)


[Ovu poruku je menjao -zombie- dana 23.11.2004. u 10:50 GMT+1]
[ sasas @ 23.11.2004. 09:49 ] @
Citat:
-zombie-: pa ovo je školski primer za upotrebu rekurzije..


...Ukoliko je u koodu iz prve poruke na mestima //Do something isti kood. Iz kasnijih poruka nije jasno da li je tako, a autor threada nas bojkotuje :)
Kad bi nam marko objasnio malo detaljnije, moglo bi se mozda dalje i razglabati na tu temu.

Citat:
(a usput, ovaj, to što si opisao, to ti neće poleteti..)


must agree on that. a i da poleti, svakako to ne bi bio kood na koji bih (bar ja) bio ponosan :)

ss.
[ Rapaic Rajko @ 23.11.2004. 11:23 ] @
Citat:
milika: Ovo je jedino moguce uz pomoc rekurzije i pokazivaca na procedure
ali to bas nije osnovni paskal...


Najcistiji Pascal koji se moze zamisliti :). S tim sto ne moras da koristis pokazivace na procedure, vec reference na iste. (Pascal: funkcije i procedure su takodje VARIJABLE, i kao takve se mogu dodeljivati, prosledjivati i ne znam sta jos).

Rajko
[ reiser @ 23.11.2004. 22:48 ] @
Citat:
sasas wrote:...Ukoliko je u koodu iz prve poruke na mestima //Do something isti kood. Iz kasnijih poruka nije jasno da li je tako, a autor threada nas bojkotuje :)
Kad bi nam marko objasnio malo detaljnije, moglo bi se mozda dalje i razglabati na tu temu.


Da, umesto // Do something ce biti isti kod - tj. najverovatnije ce se pozivati jedna ista funkcija.
Kako to resiti preko rekurzije ?
[ sasas @ 24.11.2004. 07:07 ] @
Ovo ti je otprilike kako rekurzija radi. Pogledaj kako ovo funkcionise, pa napisi novu prema svojim potrebama.

ss.

Code:

procedure sale(iNivo: integer);     // ovo je rekurzivna procedura
var
  i: integer;
begin
  if iNivo = 10 then exit;          // uslov za izlazak
  writeln;
  writeln('Nalazis se u dubini: ', iNivo);
  for i := 1 to 10 do               // ovo bi bila tvoja for petlja
  begin
    write(i, '  ');                 // do something
  end;
  inc(iNivo);
  sale(iNivo);                      // funkcija poziva samu sebe, sa novim argumentom
end;

begin
  sale(0); // prvi poziv funkcije
  readln;
end.
[ broker @ 24.11.2004. 13:31 ] @
Momci, itekako bi poletelo i radilo bi posao.

Bas bih voleo da vidim tu rekurziju koja na svakom nivou radi neki drugi posao (kao sto coveku treba) a da je jednostavna. Moze da se napravi ali cemu petljanje kad moze prosto da se resi.

Mislim, ok je voleti rekurzije, uvek je bilo fancy korsititi ih, ali ipak ne treba ih gurati u sve i svasta.
[ reiser @ 24.11.2004. 15:29 ] @
@broker
Gresis, izvrsava se jedan isti kod na svakom nivou.
[ broker @ 24.11.2004. 16:01 ] @
Marko, napisao si:

Code:

For C1 := 0 to 9 Do
Begin
  // Do something
  For C2 := 0 to 9 Do
  Begin
  // Do something
    For C3 := 0 to 9 Do
    Begin
    // Do something
    End;
  End;
End;


Iz ovoga sam protumacio da pored toga sto pokrece petlju ispod sebe, petlja izvrsava i dodatni kod koji je oznacen sa "Do Something".

Ako problem svodis na

Code:

For C1 := 0 to 9 Do
Begin
  For C2 := 0 to 9 Do
  Begin
    For C3 := 0 to 9 Do
    Begin
    // Do something
    End;
  End;
End;


Onda brate prosto izracunaj koliko puta terba da se izvrsi taj kod, mnozeci broj petlji sa brojem iteracija i napravi jednu obicnu petlju sa potrebnim brojem iteracija koja ce to sve da uradi.
[ reiser @ 24.11.2004. 21:25 ] @
OK, moracu malo vise da pojasnim problem...
Ovako, treba da napisem AI za igricu Lines. To je igra gde se crveni i plavi kruzici ubacuju odozgo i pobednik je onaj ko prvi napravi liniju (horizontalnu, vertikalnu ili dijagonalnu) od 4 istih kruzica. Sad ne bih da reklamiram, ali kome nije jasno neka vidi ovaj link
Polje za igru je velicine 10x15 (sirina=10, visina=15). U mom DLL-u sam definisao matricu koja odgovara polju ([0..9, 0..14]). Postoji i funkcija DetermineMove(const maxLine, minLine, deepCount, blobType : Integer) : Integer;
maxLine je maksimalna velicina linije za koju funkcija ispitava, minLine minimalna velicina linije. blobType je tip kruzica, da li je plavi ili crveni.
E sad, deepCount oznacava koliko poteza unapred funkcija proverava zadate uslove. Recimo, ako napisem ovako :
Code:
DetermineMove(4, 4, 0, fEnemy)
, funkcija ce napraviti samo jedan prolaz i proverice da li postoji mogucnost da se napravi linija od 4 neprijateljska kruzica u narednom potezu. Zatim, ako je deepCount = 1, funkcija proverava dva poteza unapred, tj. pravi dva prolaza kroz kod.

Otprilike tako sam zamislio tu funkciju. E sad, postoje funkcije WriteBlob(const col : Integer) : Boolean; i RemoveBlob(const col : Integer);. Njih fja DetermineMove koristi. Recimo, ako je deepCount = 0, onda funkcija treba da napravi jedan brojac, recimo C1, od 0 do 9, da u kolonu C1 pomocu fje WriteBlob() upise jedan kruzic i da ispita da li trenutni raspored odgovara zadatim parametrima. Posle toga, pomocu fje RemoveBlob() se kruzic uklanja iz kolone, kako bi se vratio stari raspored. Ako je raspored kruzica pre pozivanja RemoveBlob() fje odgovarao uslovima, izlazi se iz funkcije.
Zatim, ako se fja pozove sa deepCount=1, funkcija treba da napravi dva prolaza i da ispita sve moguce kombinacije (ili varijacije, nisam siguran). Znaci, prvo se u kolonu 0 zapise jedan kruzic pa se onda u kolone od 0 do 9 zapisuje po jos jedan i ispituje (posle toga se uklanja). Zatim se prelazi na kolonu 2, tu se upisuje kruzic, i opet se od 0..9 zapisuje jos po jedan kruzic... I tako dalje, sve dok se ne doje do situacije kad se u 9 koloni nalaze oba kruzica.

Eto celog problema, znaci ja ne znam ovo da napravim. Ona Saletova funkcija bi odgovaral za deepCount=1, ali sta ako je =2 ili vise ?

poz
[ masetrt @ 02.12.2004. 09:41 ] @
Ne bih da sigurisem , ali mislim da ti je potreban drugaciji pristup resavanju problema. naime standardi za resavanje ovakvih zadataka (tzv. sahovski problemi) koristi se mini-max funkcija (na netu gomila objasnjenja a ako ne nadjes cimni me na mail pa cu ti poslati). E sad ako je vazna brzina (ako je ono takmicenje sto mislim da jeste vazna je) postoje tehnike skracivanja kao alpha-beta cut. Pa jos ako uvedes neku heuristiku bog da te vidi (salim se).
[ reiser @ 02.12.2004. 21:51 ] @
Aj molim te posalji na paunovic [at] gmail [dot] com to sto imas

poz i hvala unapred