Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 24. 05. 2011 10:19

Pajah
Zelenáč
Příspěvky: 4
Reputace:   
 

Pascal – Rozpočítadlo

Zdravím,
dělám ročníkovou práci do programování.
Zadání: Je dán počet dětí, délka rozpočítadla a číslo dítěte, od kterého se začne počítat. Vypište čísla dětí, která postupně vypadávají.
Vše už prakticky funguje, lae zatím jsem dokonale nevyřešil to, jak přeskakovat již vyhozené děti, je tam sice cyklus while, ale nepřeskočí to na správné dítě, sice všechny děti vypadnou, ale pak už je ve správném pořadí.
Celý program je zde:

Code:

program ROZPOCITADLO;
type pole=array[1..100] of integer;
var vyp:pole;
    poc, x, delka, i, zac, out, je:integer;
function hledej(out:integer; vyp:pole):boolean;
var fi, fje:integer;
begin
     fje:=0;
     for fi:=1 to x do
     if vyp[fi]=out then fje:=fje+1;
     if fje>0 then hledej:=true else hledej:=false;
end;
begin
     x:=0;
     writeln('--- Rozpocitadlo // Pavel Hodoval ---');
     write('Zadej pocet deti: ');
     readln(poc);
     write('Zadej delku rozpocitadla: ');
          readln(delka);
     write('Od ktereho ditete se zacina? (1 az ', poc, '):');
     readln(zac);
     repeat
           if (delka+zac-1)>poc then out:=abs(poc-delka-zac+1) else out:=delka+zac-1;
           kroky:=out;
           while hledej(out,vyp)=true do
           begin
                    if (out+1)>=poc then out:=abs(poc-out-1) else out:=out+1;
           end;
           if hledej(out,vyp)=false then
           begin
             x :=x+1;
             vyp[x]:=out;
           end;
           if (out+1)>=poc then zac:=abs(poc-out-1) else zac:=out+1;
     until poc=x;
     for i:=1 to x do writeln(vyp[i]);
     readln;
end.

Předem díky za rady.

Offline

 

#2 24. 05. 2011 13:59

janca361
.
Příspěvky: 3284
 

Re: Pascal – Rozpočítadlo

↑ Pajah:
Nezkoumala jsem program, ale co tahle upravit počet dětí - odečíst vždy 1 (vypadnuté), potřeba nové proměnné pro počet již vypadnutých dětí a pak přičíst počet vypadnutých dětí k pořadí právě vypadnutého dítěte.
Je to můj návrh, třeba není nejlepší, ale já bych to asi řešila takto.

Offline

 

#3 24. 05. 2011 16:56

Pajah
Zelenáč
Příspěvky: 4
Reputace:   
 

Re: Pascal – Rozpočítadlo

Ale to neřeší můj problém, můj algoritmus v podstatě funguje, ale od určitého počtu již vyřazuje děti ve špatném pořadí (resp. je to posunuté), protože jsem zatím nevymyslel, jak jednoduše přeskočit vyhozené děti, a pak správně počítat (musí se pořád brát v úvahu délka rozpočítadla).
Dejme tomu, že máme 9 dětí, délka rozpočítadla je 3 a začíná se od dítěte s číslem 2.
1 2 3 4 5 6 7 8 9
Vypadne 4., 7., 1., 5., a pak tedy máme 2 3 6 8 9,  a korektně se má vynechat sedmé dítě, čili vypadne 9. (protože délka je3), ale program mi vyhodí osmé. Jeidné, co jsem vymyslel, je pomocí cyklu while přeskakovat vyhozené děti, ale přoád to neřeší problém toho, že to neodpovídá délce rozpočítadla.

Offline

 

#4 24. 05. 2011 17:01

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

mě by přišlo přirozený použít cyklickej spojovej seznam a z něj vyhazovat prvky, jako při tom rozpočítávání

Offline

 

#5 24. 05. 2011 17:10

janca361
.
Příspěvky: 3284
 

Re: Pascal – Rozpočítadlo

↑ Pajah:
Tak v tom případě se omlouvám, nepochopila jsem tvůj problém.

Offline

 

#6 24. 05. 2011 17:17 — Editoval Geronimo (24. 05. 2011 17:36)

Geronimo
Místo: Bruntál/Brno
Příspěvky: 292
Škola: PřF+ESF MUNI
Pozice: student
Reputace:   20 
 

Re: Pascal – Rozpočítadlo

Pajah napsal(a):

Dejme tomu, že máme 9 dětí, délka rozpočítadla je 3 a začíná se od dítěte s číslem 2.
1 2 3 4 5 6 7 8 9
Vypadne 4., 7., 1., 5., a pak tedy máme 2 3 6 8 9,  a korektně se má vynechat sedmé dítě, čili vypadne 9. (protože délka je3), ale program mi vyhodí osmé. Jeidné, co jsem vymyslel, je pomocí cyklu while přeskakovat vyhozené děti, ale přoád to neřeší problém toho, že to neodpovídá délce rozpočítadla.

Jak mas to pole (pole=array[1..100] of integer;), tak pozice bunky ti bude odkazovat na cislo ditete a do hodnoty nacti vsude ze zacatku 1 a kdyz dite vyhodis, tak to zmen na 0 a v druhem pruchodu ignoruj vsechny bunky s nulovou hodnotou.

Tak jsem se na to koukl jeste jednou a ty do toho pole uz nacitas rovnou serazene decka.

Co treba to zkusit takhle:
Vytvorit si pole a[1],a[2]...a[pocet], ktere bude mit ve vsech bunkach hodnotu 0. Potom rozbehnes algoritmus na rozpocitavani a do kazdeho bunky vepises poradi. Pokud tvuj algoritmus narazi na bunku s hodnotou ruznou od 0, tak ji preskoci.
Potom jen na konci vytvorit vhodny algoritmus na tisk.


„Jestliže neumíš – naučíme, jestliže nemůžeš – pomůžeme ti, jestliže nechceš – nepotřebujeme tě.“ —Jan Werich

Offline

 

#7 24. 05. 2011 19:22

Pajah
Zelenáč
Příspěvky: 4
Reputace:   
 

Re: Pascal – Rozpočítadlo

Tehn while cyklus skroo na začátku repeatu (while hledej(ou,tvyp)=true.... zajišťuje přeskočení všech (i víc za sebou) vyhozených dětí, ale jde o to, že to pak nevyhazuje správně. Prostě to korektně třeab z 6 přeskočí na 8, protože 7 je vyloučená, ale délka rozpočítadla je 3, čili to přeskočilo pouze o 2 kroky. A nenapadá mě jak dopočítávat zbylé kroky, které jsou ještě potřeba.

Offline

 

#8 24. 05. 2011 19:42

mák
Místo: Vesmír, Galaxie MD
Příspěvky: 920
Reputace:   63 
 

Re: Pascal – Rozpočítadlo

Pascal neumím, ale takhle to vypadá v Maximě (hotová funkce):

Code:

fRozpoc(L,n):=block([d,e,i,Z,k],
    k: 0,
    Z: [],
    d: length(L),
    e: d,
    for i:1 thru e do (
        k: mod(k+(n-1),d),
        Z: append(Z,[L[k+1]]),
        L: delete(L[k+1],L),
        d: d-1,
        print(d," - ",Z," - ",L)
    ), Z
)$

Komentář k některým řádkům:

Code:

k: mod(k+(n-1),d)

k: je index v poli, pomocí funkce modulo se počítá následující index (k+(n-1)), (n-1) je tam proto, že další člen není o n pozic dále, ale pouze o (n-1) pozic, protože jeden žák "jde ven". Pozor, Pole L nemá konstantní délku d, ale vždy ubyde jeden žák!

Code:

Z: append(Z,[L[k+1]])

L je pole všech žáků (odsud je vybíráme)
L[k+1] je aktuálně vybraný žák (maxima má pole začínající od 1 takže [k+1], Pascal začíná od 0, takže v pascalu bude pouze index k)
Z je prázdné pole do kterého postupně přesouváme vybrané žáky (funkce append připojí položku na konec pole)

Code:

L: delete(L[k+1],L)

Tento řádek odstraní vybraného žáka z původního pole

Code:

d: d-1

vybráním žáka se nám délka pole zmenší (počet žáků ubyde), je nutné odpočítat 1, aby předcházející funkce modulo počítala správně.

Code:

print(d," - ",Z," - ",L)

pouze pro odladění, vypisuje každý krok počet zbývajících žáků, obsah pole nevybraných žáků (postupně ubývá) a obsah pole vybraných žáků (postupně přibývá).

Z je pole žáků které vrací funkce

Code:

[3,6,9,2,7,1,8,5,10,4]

To je výsledek pro 10 žáků pro výběr každý třetí.


LibreOffice Verze: 25.8.4.2, Maxima 5.49.0 (SBCL)

Offline

 

#9 24. 05. 2011 20:01

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

↑ mák: a já zase umím udělat kotrmelec. obojí je zhruba stejně relevantní;)

Offline

 

#10 24. 05. 2011 23:29

mák
Místo: Vesmír, Galaxie MD
Příspěvky: 920
Reputace:   63 
 

Re: Pascal – Rozpočítadlo

↑ Stýv:
Na programu Maxima jsem popsal krok za krokem algoritmus který řeší daný problém. Myslím si, že člověk který zvládá Pascal, by jej do něj dokázal přepsat. Já osobně, kdyby mi někdo popsal krok za krokem algoritmus řešení nějaké úlohy, jsem jej schopen napsat v programovacím jazyku který znám.

Chtěl jsem pouze pomoct.
Omlouvám se.


LibreOffice Verze: 25.8.4.2, Maxima 5.49.0 (SBCL)

Offline

 

#11 25. 05. 2011 00:08

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

↑ mák: problém je, že pole v pascalu mají pevnou dýlku a nejde takhle přidávat prvky na konec nebo odebírat odprostředka. proto mi tvůj algoritmus v maximě přijde celkem k ničemu. ale co já vim, třeba to autorovi pomůže

neber si to tak, já jsem poslední dobou asi moc kousavej

Offline

 

#12 25. 05. 2011 09:09

Pajah
Zelenáč
Příspěvky: 4
Reputace:   
 

Re: Pascal – Rozpočítadlo

Asi by bylo nejlepší, kdybyste si můj program zkusili zkompilvoat, abyste pochopili můj problém. Ten program v Maximě mi orpavdu nepomžůže, takhle s iv Pascalu s poli hrát nemůžu, ale samozřejmě díky za snahu o pomoc. Jeidný můj problém je, jak vymyslet nějaký další algoritmus, kteřý zařídí, že se správně posune "ukazatel" tak, aby posunutí fungovalo správně. První kolo vyhazování je v pořádku, po druhém už to dělá špatné pořadí.

Offline

 

#13 25. 05. 2011 10:39

Geronimo
Místo: Bruntál/Brno
Příspěvky: 292
Škola: PřF+ESF MUNI
Pozice: student
Reputace:   20 
 

Re: Pascal – Rozpočítadlo

↑ Pajah:

Me to ani nezkompilovalo. Na 24. radku to haze chybu, ze nemuze nejit 'kroky'.
A kdyz se tak divam, tak s tou promennou potom nikde nepracujes, takze nechapu, proc ji tam mas.


„Jestliže neumíš – naučíme, jestliže nemůžeš – pomůžeme ti, jestliže nechceš – nepotřebujeme tě.“ —Jan Werich

Offline

 

#14 25. 05. 2011 12:45

musixx
Místo: Brno
Příspěvky: 1771
Reputace:   45 
 

Re: Pascal – Rozpočítadlo

↑ Pajah: Ale můžeš v Pascalu udělat to samé. Pole se nebude prodlužovat, ale zkracovat. Ale je trochu programátorsky (matematicky) neobratné při každém vyřazení překopírovávat kus pole o jednu pozici.

Offline

 

#15 25. 05. 2011 13:00 — Editoval Honzc (25. 05. 2011 13:01)

Honzc
Příspěvky: 4647
Reputace:   248 
 

Re: Pascal – Rozpočítadlo

↑ Pajah:
Tohle mi pracuje.

type Tpole=array[1..100] of Integer;
var naz,vyp: Tpole;
    i,j,poc,delka,zac,zb,a: Integer;

procedure Napln(var s: Tpole; n: Integer);
var i: Integer;
begin
  for i := 1 to n do
    s[i] := i;
end;

begin
  WriteLn('--------- Rozpocitadlo ----------');
  Write('Zadej pocet deti: ');
  ReadLn(poc);
  Write('Zadej delku rozpocitadla: ');
  ReadLn(delka);
  Write('Od ktereho ditete se zacina? (1 az ', poc, '): ');
  ReadLn(zac);
  Napln(naz,poc);
  i := zac;
  j := 0;
  a := 0;
  zb := 1;
  while zb<=poc do
  begin
      if naz[i]<>0 then
        a := a+1;
      if a=delka then
      begin
        j := j+1;
        vyp[j] := naz[i];
        naz[i] := 0;
        a := 0;
        zb := zb+1;
      end;
      i := i+1;
      if i-1=poc then
        i := 1;
  end;
  WriteLn;
  WriteLn('Poradi vypadnutych deti');
  for i := 1 to poc do
    Write(vyp[i],' ');
  WriteLn;
  ReadLn;
end.

Offline

 

#16 25. 05. 2011 13:16

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

↑ Honzc: a co to udělá, když zadáš 101 dětí?

Offline

 

#17 25. 05. 2011 13:26

Honzc
Příspěvky: 4647
Reputace:   248 
 

Re: Pascal – Rozpočítadlo

↑ Stýv:
To neřeším, i když ošetrení by bylo velice jednoduché.
Jeden repeat a je to. (psalo by to na začátku nuly)
Není také ošetřeno,když se zadají písmena, nebo se začíná na dítěti, které neexistuje. (zac>poc)

Offline

 

#18 25. 05. 2011 14:11

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

↑ Honzc: neni mi úplně jasný, jak by jeden repeat vyřešil to, že máš pole fixní velikosti a snažíš se do něj nacpat víc čísel

trvám na tom, že by se úloha měla řešit pomocí spojáku, ne pole

Offline

 

#19 25. 05. 2011 14:23 — Editoval musixx (25. 05. 2011 14:27)

musixx
Místo: Brno
Příspěvky: 1771
Reputace:   45 
 

Re: Pascal – Rozpočítadlo

↑ Stýv: Já bych na (cyklickém) zřetězeném seznamu netrval, školské úlohy nemají problém v tom, že fungují jen v nějakých mezích. Přítomnost dítěte jde kódovat jednobitově, i tak by se paměť dala šetřit, ale o to jistě vůbec nejde. V listu bys zase při každém vyřadění musel dealokovat paměť, takže programátorsky de facto stejně náročné jako vyhodnocování naz[] u ↑ Honzc:.

Jsme na matematickém fóru. Nešla by najít funkce f() taková, abychom prostě mohli psát jen

Code:

FOR i FROM 1 TO pocet_deti DO PRINT(f(i, pocet_deti))

?

Offline

 

#20 25. 05. 2011 14:26 — Editoval Honzc (25. 05. 2011 14:27)

Honzc
Příspěvky: 4647
Reputace:   248 
 

Re: Pascal – Rozpočítadlo

↑ Stýv:
No asi tak, že mu nedovolíš zadat větší číslo (a zároveň menší než 1, bavíme se o přirozených číslech) než máš "délku" (velikost) pole.
Tedy např pro délku 100.

Write('Zadej pocet deti: ');
ReadLn(poc);
if (m<1)or(m>100) then    //Pokud zadame cislo mimo interval
  repeat                          //tak to nedovolime
    WriteLn('Pocet deti musi byt cele cislo z intervalu <1,100>');
    WriteLn;
    Write(Zadej pocet deti: ');
    ReadLn(poc);
  until (m>=1)and(m<=100);

Offline

 

#21 25. 05. 2011 14:30

musixx
Místo: Brno
Příspěvky: 1771
Reputace:   45 
 

Re: Pascal – Rozpočítadlo

↑ Honzc: Tak takového ošetření nebude to, co měl Stýv na mysli. Souhlasím s ním, ale současně jsem se pro účel umění sestavit a otestovat potřebný algoritmu zastal výše tebe.

Offline

 

#22 25. 05. 2011 14:39

Stýv
Vrchní cenzor
Příspěvky: 5710
Reputace:   215 
Web
 

Re: Pascal – Rozpočítadlo

↑ musixx: vidíš, já bych naopak na spojáku trval, protože je to školní úloha, tak by se měl naučit je používat (navíc mi fakt přijde, že tahle úloha si o cyklickej spoják vyloženě říká)

Offline

 

#23 25. 05. 2011 14:58 — Editoval musixx (25. 05. 2011 15:05)

musixx
Místo: Brno
Příspěvky: 1771
Reputace:   45 
 

Re: Pascal – Rozpočítadlo

↑ Stýv: ok. Těžko říct, co má úloha prověřit/naučit. Možná modulární aritmetiku.

Offline

 

#24 25. 05. 2011 20:13

Honzc
Příspěvky: 4647
Reputace:   248 
 

Re: Pascal – Rozpočítadlo

↑ Stýv:
Já teda nevím, proč by se nemohlo použít pole.
Nevím jestli  v čistém Pascalu existuje procedura SetLength(), pomocí které je možné zadat velikost pole až ze známé
hodnoty jeho délky, ale v Delphi určitě existuje. Existuje i pro konzolové aplikace psané v Delphi. Pochybuju, že dnes někdo píše programy pouze v čistém Pascalu.
Já jsem chtěl kolegovi pouze ukázat jak se dá vyřešit jeho problém a použil jsem již jím definovaných proměnných (a tedy i pole dané fixní délky). Neřešil jsem tedy zda použít to nebo ono. Jak ty víš co jim ve škole řekli, že se má použít.

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson