Programiranje

Pascal: školski zadaci

emerik čet 30.9.2010 19:33

Znači treba napisati program u kojem upisujemo 3 broja i on računa da li za njih vrijedi Pitagorin uvjet.Program mi izbacuje grešku:"18 / 11 pitago~1.pas
  Fatal: Syntax error, THEN expected but := found".Zanima me dali je algoritam za računanje srednjeg broja dobar.Hvala na pomoći.

 

program Pitagorin_uvjet;
var a,b,c,max,min,sred:integer;
begin
writeln('Upisi 3 broja da provjerimo Pitagorin uvjet');
readln(a,b,c);
max:=a;
if b > max then max:=b;
if c > max then max:=c;

min:=c;
if b < c then min:=b;
if a < b then min:=a;

sred:=b;
if (a > sred) and (a < c) then sred:=a;
if (c > sred) and (c < a) then sred:=c;

if max*max:=((min*min) + (sred*sred)) then
writeln('Ovi brojevi zadovojlavaju Pitagorin uvjet')
else writeln('Ovi brojevi ne zadovoljavaju uvjet');
readln;
end.

dragans čet 30.9.2010 20:00

Umjesto

if max*max:=((min*min) + (sred*sred)) then

ide

if max*max = ((min*min) + (sred*sred)) then  //:= (dvotačka jednako) je u Pascalu operator dodjeljivanja,  a = (jednako) je operator poređenja

 

ili ovako malo jasnije:

 

if (max*max = ((min*min) + (sred*sred))) then  //cijeli Boolean izraz bi trebalo stavljati u zagrade sem najjednostavnijih da ne zbunjujes kompajler

 

ako taj Pascal koji koristis ima funkciju SQR (kvadrat broja) onda moze i ovako

 

if (SQR(max) = (SQR(min) + (SQR(sred))) then

 

 

 

emerik čet 30.9.2010 21:14
dragans kaže...

Umjesto

if max*max:=((min*min) + (sred*sred)) then

ide

if max*max = ((min*min) + (sred*sred)) then  //:= (dvotačka jednako) je u Pascalu operator dodjeljivanja,  a = (jednako) je operator poređenja

 

ili ovako malo jasnije:

 

if (max*max = ((min*min) + (sred*sred))) then  //cijeli Boolean izraz bi trebalo stavljati u zagrade sem najjednostavnijih da ne zbunjujes kompajler

 

ako taj Pascal koji koristis ima funkciju SQR (kvadrat broja) onda moze i ovako

 

if (SQR(max) = (SQR(min) + (SQR(sred))) then

 

 

 

  Joj da,glupa greška,sorry,tek 3. tjedan učim Pascal.

mbaksa pet 1.10.2010 02:28
dragans kaže...
if (max*max = ((min*min) + (sred*sred))) then  //cijeli Boolean izraz bi trebalo stavljati u zagrade sem najjednostavnijih da ne zbunjujes kompajler

Bez brige, to ne zbunjuje kompajler. Tim vise sto su kompajleri za Pascal u pravilu vrlo precizni sto se tice prijavljivanja sintaktickih gresaka, za razliku recimo od C++ kompajlera, koji kad fulas neku sitnicu i jednoj naredbi odjednom imas deset gresaka i to u datotekama koje prvi put u zivotu vidis (datotekama koje su dio biblioteka koje koristis).

 

Vanjske zagrade su u Pascalu nepotrebne. Meni osobno je preglednije bez njih, a ako pogledas izvorni kod programa koji dolaze s kompajlerom za Pascal (a mislim i Delphi), vidis da u pravilu ne stavljaju vanjske zagrade. To se udomacilo kao nepisano pravilo. U C/C++-u zagrade moraju ici iz razumljivih razloga - tamo nema rezervirane riječ then.

mbaksa pet 1.10.2010 04:34
emerik kaže...

Znači treba napisati program u kojem upisujemo 3 broja i on računa da li za njih vrijedi Pitagorin uvjet.

Inace, u svom programu se uopce ne moras muciti sa srednjim i najmanjim brojem - bitno je samo da znas koji ti je najveci. Proanaliziraj ovaj primjer:

 

program Pitagorin_uvjet;

procedure Zamijeni(var x: Integer; var y: Integer);
var
  tmp: Integer;
begin
  tmp := x;
  x := y;
  y := tmp;
end;

var
  a, b, c: Integer;
begin
  WriteLn('Upisi 3 broja da provjerimo Pitagorin uvjet');
  ReadLn(a, b, c);

  if c < b then Zamijeni(c, b);
  if c < a then Zamijeni(c, a);

  if c*c = a*a + b*b then
    WriteLn('Ovi brojevi zadovoljavaju Pitagorin uvjet')
  else
    WriteLn('Ovi brojevi ne zadovoljavaju uvjet');
end.

 

U ovom primjeru koriste se tri originalne varijable (a, b, c), a njihove vrijednosti ce funkcija Zamijeni - naravno, zamijeniti. Primijeti da argumentima funkcije Zamijeni prethodi rezervirana rijec var - ona znaci da se argumenti prenose kao reference - dakle, mijenjanjem sadrzaja varijable x ili y, zapravo se mijenjaju vrijednosti varijable koje su argumenti funkcije Zamijeni u glavnom dijelu programa.

 

Mozda ti ovo sad jos ne treba, ali nekad u buducnosti bi moglo. Recimo kod sortiranja - napisat ces si slicnu proceduru za zamjenu vrijednosti.

emerik čet 21.10.2010 20:27

Imam još jedan problem.Treba napisati program koji ispisuje sve proste brojeve do 100.U čemu je problem?

program prvi;
var i,j,bd:integer;
begin
bd:=0;
for j:= 2 to 1000 do
begin
for i:= 1 to (j-1) do
if (j-1) mod i = 0 then
bd:=bd+1;
if bd = 0 then writeln(i);
end;
readln;
end.

 

mbaksa pet 22.10.2010 01:51

Kao prvo - uvlaci hijerarhijski nize naredbe! Ako ih jesi uvlacio i ovaj editor ti unisti razmake na pocetku, onda i ponovno uvuci ovdje u editoru teksta da stvar bude pregledna, jer se inace iz koda ne moze iscitati sto se u kojoj petlji vrti! Dakle, kod ti izgleda ovako:

 

program prvi;
var i,j,bd:integer;
begin
  bd:=0;
  for j:= 2 to 1000 do
  begin
    for i:= 1 to (j-1) do
      if (j-1) mod i = 0 then
        bd:=bd+1;
    if bd = 0 then writeln(i);
  end;
  readln;
end.

Kod sad dobiva posve drugaciju sliku! Sad se jasno vidi da vrtis dvije petlje i sto se dogadja u kojoj petlji.

 

U kodu si napravio tesku logicku gresku (zapravo vise njih) - zbog toga ti ne ispisuje ni jedan broj. Naime, ispisat ce vrijednost varijable i kad je varijabla bd jednaka nuli. A varijabla bd je jednaka nuli samo na pocetku!

 

Prva greska koju si napravio je ta da si naredbu bd:=0; stavio izvan svih petlji! Znaci, kad se prvi put dodje do broja koji nije prim broj, bd vise nije nula i program ce ti za svaki broj nakon toga, bio on prim broj ili ne, misliti da nije prim broj.

 

Druga greska koju si napravio je ta sto ti varijabla i ide od 1, a ti kazes da je broj prim broj ako nije dijeljiv s niti jednim drugim brojem (stavio si uvjet bd = 0)! Dakle, posto je svaki broj dijeljiv s jedan, bd ti je za svaki broj veci od nule i stoga ispada da ne postoje prim brojevi. Dakle, ili trebas provjeravati bd = 1 ili tako nesto.

 

Treca greska - zasto provjeravas je li j-1 dijeljivo s  i, kad ti je cijeli smisao vanjske petlje da provjeravas dijeljivost broja  j, a ne broja  j-1? Dalje, pazi sto si s tim napravio - s tim ti ispada da je 4 prim broj! Jer (4-1) je 3!

 

Cetvrta greska - ispisujes varijablu i! Jesi li dijelio i s j ili si dijelio j s i? Kad se odvrti unutrasnja petlja, na kraju te petlje i iznosi j-1, znaci broj za jedan manji od j - od onog broja za koji pokusavas utvrditi je li prim broj!

 

 

Peto - nije greska kao takva, ali dobro je znati. Unutarnju petlji (petlju for i := ...) treba prekinuti u trenutku kad se utvrdi da broj nije prim broj, naredbom  break; Naime, recimo da si kod broja 998 - kakvog smisla ima vrtiti unutarnju petlju 997 ili koliko vec puta, ako znas da to nije prim broj cim ga podijelis s brojem 2? Dakle, to treba izgledati:

 


if (j-1) mod i = 0 then
begin
    bd:=bd+1;
      break; 
end;

 

Ako cemo cjepidlaciti, varijabla bd je trebala biti tipa Boolean, posto broj ili je ili nije prim broj. Dakle, ispravan kod bio bi:

 

program prvi;
var
    i, j: Integer;
    prim: Boolean;
begin
    for j:= 2 to 1000 do
    begin
      prim := true;

      for i := 2 to (j-1) do
        if j mod i = 0 then
        begin
          prim := false;
          break;
        end;

      if prim then Write(j, ' ');
    end;
    ReadLn;
end.

 

Luuka čet 28.10.2010 18:33
emerik kaže...

Možete mi taj posljednji zadatk riješiti drugačije,jer još nismo učili boolena i ne smijemo koristiti.

Možeš zamijenit taj boolean sa jednim integerom, koji će biti 0 ili 1. I sve ostalo je isto :D

emerik čet 18.11.2010 17:42

Evo mene opet,imam još jedno pitanje.Znači,program mora upisani broj podijeliti na 2 dijela tako da zbroj tih dvaju dijelova mora biti najmanji.Zbroj drugih dijelova kad ih zbrojimo mora biti veći.U programu se smije koristiti SAMO repeat petlja.Moj program radi za sve brojeve osim za desetice ,stotice,tisućice...

EDIT:Ne znam zašto je kod ovako napisao.

 

program osmi;
      var s,x,pom,zb,j,i,m,pom1,min,zam:longint;
begin
writeln ('Upisi broj');
readln(x);
m:=1;
i:=0;
j:=0;
min:=x;
zam:=x;
      repeat
        pom1:= x mod 10;
        i :=i+1 ;
        x:=x div 10;
        until pom1 = 0 ;
      repeat
        s:=0;
        zb:= zam mod m ;
        pom:=zam div m;

        j:=j+1;
        s:=s+pom+zb;
        if s < min then min:=s;
        m:=m*10;
      until j = i ;

writeln('Najmanja suma je : ',min);
readln;
end.




mbaksa čet 18.11.2010 18:08
emerik kaže...

Evo mene opet,imam još jedno pitanje.Znači,program mora upisani broj podijeliti na 2 dijela tako da zbroj tih dvaju dijelova mora biti najmanji.Zbroj drugih dijelova kad ih zbrojimo mora biti veći.U programu se smije koristiti SAMO repeat petlja.Moj program radi za sve brojeve osim za desetice ,stotice,tisućice...

Sorry, ne razumijem zadatak. Daj primjer.

emerik čet 18.11.2010 18:13

Znači dam npr. broj 123.Mogu ga podijeliti da 2 načina. na brojeve 1 i 23 ili na brojeve 12 i 3.Brojevi 12 i 3 imaju manju sumu nego brojevi 23 i 1 i zato ispišem njihovu sumu.EDIT:MIslim da sam ispravio grešku u prvoj repeat petlji sam stavio until x = 0 ,a ne pom = 0 i onda dobivam dobra rejšenja.

mbaksa čet 18.11.2010 18:34
Frentt kaže...

imam i ja jedan zadatak:

Trebam upisati broj br, a program bi trebao ispisati da li je taj broj paran ili neparan.

UPOZORENJE:Ne smiju se koristi nikakve naredbe petlje ili grananja

znači nema if,for,while

Fora zadacic...

 

program paran;
var  br: Integer;
const  parnost: array[0..1] of string = ('paran', 'neparan');
begin  WriteLn('Upisi broj: ');  ReadLn(br);
  WriteLn('Broj ', br, ' je ', parnost[br mod 2], '.');
  ReadLn;end.

Plahi uto 7.12.2010 21:15

Gdje griješim? Stalno mi izbacuje 0.

 

Program slucajni_odabir;
var x:integer;
    izbor:char;
 begin
   repeat
   writeln('Pritisnite enter za pocetak:');
    readln(izbor);
      if izbor='enter' then
     x:= random(29);
    writeln('Vas broj je: ',x);
    writeln('Zelite li jos jednom? d/n');
     readln(izbor);
  until izbor='n';
  readln;

end.

Dr. Zoidberg uto 7.12.2010 21:24
Plahi kaže...

Gdje griješim? Stalno mi izbacuje 0.

 

Program slucajni_odabir;
var x:integer;
      izbor:char;
  begin
    repeat
    writeln('Pritisnite enter za pocetak:');
      readln(izbor);
          if izbor='enter' then
        x:= random(29);
      writeln('Vas broj je: ',x);
      writeln('Zelite li jos jednom? d/n');
        readln(izbor);
  until izbor='n';
  readln;

end.

  Nisam taknuo paskal stoljećima, a ni kada sam ga dirao nisam ga znao :P Sad kad smo to rješili...

 

Pretpostavljam da ti ne ulazi u petlju. ReadLn funkcija ignorira return, tako da ti je varijabla izbor prazna i nikad ne postaje string "enter". Pretpostavljam da dobiješ nulu jer se varijabla x postavlja na nulu na početku programa a s obzirom da ti nikad ne uđe u if petlju x se nikad ne promjeni.

Plahi uto 7.12.2010 21:28
Dr. Zoidberg kaže...
Plahi kaže...

Gdje griješim? Stalno mi izbacuje 0.

 

Program slucajni_odabir;
var x:integer;
    izbor:char;
  begin
   repeat
   writeln('Pritisnite enter za pocetak:');
    readln(izbor);
      if izbor='enter' then
     x:= random(29);
    writeln('Vas broj je: ',x);
    writeln('Zelite li jos jednom? d/n');
     readln(izbor);
  until izbor='n';
  readln;

end.

  Nisam taknuo paskal stoljećima, a ni kada sam ga dirao nisam ga znao :P Sad kad smo to rješili...

 

Pretpostavljam da ti ne ulazi u petlju. ReadLn funkcija ignorira return, tako da ti je varijabla izbor prazna i nikad ne postaje string "enter". Pretpostavljam da dobiješ nulu jer se varijabla x postavlja na nulu na početku programa a s obzirom da ti nikad ne uđe u if petlju x se nikad ne promjeni.

Ne kužim te... {#}... podebljano je zapravo program i ne kužim u čemu je problem. Ovo repeat je samo da bi izabrali da li da ponovimo operaciju. Možeš mi napisati svoju verziju? Ali nemoj koristiti stringove jer ih ne kužim...

Ige uto 7.12.2010 21:33

Program slucajni_odabir;
var x:integer;
    izbor:char;
 begin
   repeat

     x:= random(29);
    writeln('Vas broj je: ',x);
    writeln('Zelite li jos jednom? d/n');
     readln(izbor);

  until izbor='n';
  readln;

end.  

 

evo ga, generira slučajni broj, pita zelite li jos jednom, ako napises d vrti se jos jedanput, ako napises n prestane se vrtit

 

edit: a ovo ti je točno što je napisao kolega prije mene, readln ti ne može učitat enter.

Dr. Zoidberg uto 7.12.2010 21:34

Mislim da ti problem leži u

 

writeln('Pritisnite enter za pocetak:');

readln(izbor);
if izbor='enter' then

 

Kada stisneš enter, varijabla izbor ti ostaje prazna. Jer ReadLn ne čita enter.

i onda ti ne ulazi u petlju i ne izvršava

 

x:= random(29);

 

te ti ne dobijaš nasumični broj.

 

probaj ovako, bez uvjeta za početak.


Program slucajni_odabir;
var x:integer;
izbor:char;
begin
    repeat
    writeln('Pritisnite enter za pocetak:');
    readln(izbor);
    x:= random(29);
    writeln('Vas broj je: ',x);
    writeln('Zelite li jos jednom? d/n');
    readln(izbor);
until izbor='n';
readln;

end.

 

  Evo pretekoše me :)

 

 

mbaksa sri 8.12.2010 00:21
Ige kaže...
edit: a ovo ti je točno što je napisao kolega prije mene, readln ti ne može učitat enter.

Zapravo, to bas i nije tocno. Idemo prvo rijesiti prvi problem - covjek je napravio uvjet koji NIKAD ne moze biti zadovoljen, kao sto rece Zoidberg - tj. isto je kao da tu naredbu nije ni napisao!

 

Znaci, napisao je:

 

if izbor='enter' then
     x:= random(29);

 

Medjutim, nije stvar ni samo u tome da, navodno zbog toga sto ReadLn nece procitati enter, da ta varijable nikad nece postati 'enter'. Osnovni problem je u tom sto je varijabla izbor tipa char, sto znaci da moze sadrzavati samo jedan jedini znak! A jedan znak NIKAD ne moze biti jednak stringu 'enter' (pet znakova). Znaci - treba nauciti tipove podataka.

 

Dalje, ideja da ce pritiskom na tipku enter varijabla poprimiti vrijednost 'enter' je pomalo smijesna - to bi bilo kao da svaki put kad stisnes tipku enter, da se zapravo otkuca pet slova (e, n, t, e, r)!

 

Idemo sad na citanje entera - sto je enter (ili return)? Enter se reprezentira ASCII znakom koda 13. Znaci, njegov redni broj, njegova decimalna reprezentacija je broj 13. Kako dobiti broj znaka u Pascalu? Funkcijom Ord. Znaci, je li pritisnut enter, moze se otkriti uvjetom:

 

if Ord(izbor) = 13 then WriteLn('Pritisnut je enter!');

Dakle, i ReadLn moze ocitati Enter. Provjerio u FPC-u. {#}

 

 

--------------------

 

Zelim se osvrnuti i na jos jednu logicku gresku, koju je i Zoidberg primijetio (iako je spominjao "petlju" - medjutim, konstrukcija if-then, odnosno if-then-else nije petlja, nego uvjet) - znaci, kod ide:

 

if izbor='enter' then
x:= random(29);
writeln('Vas broj je: ',x);

 

Treca linija, dakle ova koja pocinje s writeln, ispisat ce se uvijek - cak i kad nije definiran x (odnosno ostaje inicijalno 0). Da bi se izbjegle takve logicke greske, dobro je cijelu if-then naredbu napisati u jednom retku (if-then-else moze i u vise redaka), na primjer:

 

if izbor='enter' then x:= random(29);
writeln('Vas broj je: ',x);

 

Sad je odmah jasno da linija koja pocinje s writeln nema nikakve veze s uvjetom if, dakle sad bi svatko trebao relativno lako uociti da tu "nesto" ne stima. Jos je bolje iza konstrukcije if ostaviti jedan red prazno.

Plahi sri 8.12.2010 20:10

Program prvi;
var x,i:integer; superprost:boolean; izbor:char;
 begin
    repeat
    writeln('Upisi neki broj:');
     readln(x);
      superprost:=true;
   repeat
     for i:=2 to round(sqrt(x)) do
      if x mod i=0 then
       superprost:=false;
       x:=x div 10;
   until x=0;
     if superprost=true then
      writeln('Broj je superprost!')
     else
      writeln('Broj nije superprost!');
      writeln('Zelite li ponovno? d/n');
    until izbor='n';
    readln;
end.

 

Ne pita me za izbor, nego sam nastavlja program. Gdje je greška? Vjerojatno negdje u poretku... Ili, kako bi vi riješili?

mbaksa sri 8.12.2010 20:15
Plahi kaže...
Ne pita me za izbor, nego sam nastavlja program. Gdje je greška? Vjerojatno negdje u poretku... Ili, kako bi vi riješili?

Zasto bi te pitao za unos vrijednosti u varijablu izbor? Oznaci u kodu naredbu u kojoj bi te trebao pitati za izbor! {#} Ne mozes? E pa to je zato sto je nisi napisao. Program radi samo ono sto mu ti napises da radi. Kako nisi napisao da te trazi unos varijable izbor, on to ni ne cini. Isto kao sto ti nece ispisati pi na deset decimala - zasto bi ti to ispisao, ako nisi zadao/napisao tu naredbu?

Plahi sri 8.12.2010 20:24
mbaksa kaže...
Plahi kaže...
Ne pita me za izbor, nego sam nastavlja program. Gdje je greška? Vjerojatno negdje u poretku... Ili, kako bi vi riješili?

Zasto bi te pitao za unos vrijednosti u varijablu izbor? Oznaci u kodu naredbu u kojoj bi te trebao pitati za izbor! {#} Ne mozes? E pa to je zato sto je nisi napisao. Program radi samo ono sto mu ti napises da radi. Kako nisi napisao da te trazi unos varijable izbor, on to ni ne cini. Isto kao sto ti nece ispisati pi na deset decimala - zasto bi ti to ispisao, ako nisi zadao/napisao tu naredbu?

Kakvu naredbu da me pita? Nije dovoljno " until izbor='n'; " ?