Autorské riešenie
[stiahni]

  • Počet riešiteľov: 17 / 23 = 73,9 %

  • Úspešnosť riešenia: 4,24 / 6 = 70,7 %

Úlohu o opakovanom meraní hmotnosti 16 hárkov A4 papiera na hodine fyziky je užitočné rozdeliť si na tieto časti:

  • namerané hodnoty z textových polí uložiť do novej premennej typu zoznam,
  • nájsť v tomto zozname najmenšiu hodnotu,
  • nájsť v tomto zozname najväčšiu hodnotu,
  • vypočítať priemer hodnôt bez najmenšej a najväčšej hodnoty (ak najmenšia alebo najväčšia hodnota je v zozname viackrát, vylúčime ju z výpočtu len raz),
  • na záver určiť hmotnosť jedného hárku papiera.

Načítanie do zoznamu:

Načítanie je možné vykonať rôznymi spôsobmi, prehľadný spôsob je tento:

   urobtu "zoznam []
   urobtu "zoznam vlozPosledny meranie1'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie2'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie3'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie4'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie5'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie6'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie7'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie8'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie9'hodnota :zoznam
   urobtu "zoznam vlozPosledny meranie10'hodnota :zoznam

Rýchlo by sme však zistili, že aj keď na prvý pohľad je to zápis pekný, pri veľkom počte hodnôt nie je veľmi efektívny. Isté vylepšenie nám ponúka príkaz veta, ktorý nám umožní tento zápis skrátiť takýmto spôsobom:

   urob "hodnoty (veta meranie1'hodnota meranie2'hodnota meranie3'hodnota meranie4'hodnota
     meranie5'hodnota meranie6'hodnota meranie7'hodnota meranie8'hodnota meranie9'hodnota
     meranie10'hodnota)

Opäť ale vidíme, že pri veľkom počte prvkov aj táto možnosť zlyhá. Ukážme si teda jedno z riešení, v ktorom využijeme na načítavanie prvkov cyklus opakuj.

   urobtu "zoznam []
   opakuj 10 [
      urobTu "zoznam vlozPosledny (vykonaj slovo "meranie pocitadlo) :zoznam
   ]

Takto si už s načítavaním poradíme aj pre skutočne veľký počet meraní.

Nájdenie najmenšej a najväčšej hodnoty a výpočet priemeru zo zvyšných hodnôt - prvý spôsob:

Ak už máme namerané hodnoty načítané v zozname, postup pri hľadaní najmenšej a najväčšej hodnoty môže byť taký, že za najmenší a najväčší prvok najprv označíme hneď prvý prvok zoznamu. Postupne však potrebujeme skontrolovať ďalšie prvky. Ak sme zistili, že niektorý ďalší prvok je menší alebo väčší, tak jeho hodnotu označíme za najmenší alebo najväčší prvok a navyše si zapamätáme jeho pozíciu v zozname. Je to možné naprogramovať takto:

   urobtu "najmensi prvok 1 :hodnoty
   urobtu "najvacsi prvok 1 :hodnoty
   urobtu "poziciaNajmensi 1
   urobtu "poziciaNajvacsi 1
   prePrvky "hodnota :zoznam [
     ak :hodnota < :najmensi [urobtu "najmensi :hodnota urobtu "poziciaNajmensi pocitadlo]
     ak :hodnota > :najvacsi [urobtu "najvacsi :hodnota urobtu "poziciaNajvacsi pocitadlo]
   ]

merania.png

Ak poznáme pozíciu najmenšieho a najväčšieho prvku, tak pri spočítavaní hodnôt (aby sme vypočítali priemer) tento najmenší a najväčší prvok vynecháme. Dosiahneme to pomocou podmienky ak, v ktorej budeme kontrolovať, či nie sme na pozícii najmenšieho alebo najväčšieho prvku. Ak áno, tak danú hodnotu do súčtu nezarátame.

   urobtu "sucet 0
   opakuj pocet zoznam [
     ak (zaroven pocitadlo <> :poziciaNajmensi pocitadlo <> :poziciaNajvacsi) [
       urobtu "hodnota prvok pocitadlo :zoznam
       urobtu "sucet :hodnota + :sucet
       ]
   ]
   urobtu "priemer :sucet / 8

Tým máme vypočítanú priemernú hodnotu ôsmich meraní (nie však hmotnosť jedného hárku!)

Nájdenie najmenšej a najväčšej hodnoty a výpočet priemeru zo zvyšných hodnôt - druhý spôsob:

Druhý, rovnako správny, postup využíva to, že hodnoty zoznamu utriedíme od najmenšieho po najväčší pomocou príkazu utried a z utriedeného zoznamu odstránime prvý a posledný prvok:

   urobTu "zoznam utried :zoznam
   urobTu "zoznam bezPr :zoznam
   urobTu "zoznam bezPo :zoznam

Alebo to isté vieme spraviť aj v jednom riadku:

   urobTu "zoznam bezPr bezPo utried :zoznam

Takýto príkaz najprv zoznam utriedi, potom vytvorí zoznam bez posledného prvku a nakoniec vytvorí zoznam bez prvého prvku. Následne budeme počítať priemer už všetkých prvkov zoznamu (lebo najmenší a najväčší sme už vymazali). Ak bolo najmenších a najväčších hodnôt viac, tak sme vymazali len jednu.

   urobtu "sucet 0
   opakuj pocet zoznam [
     urobtu "hodnota prvok pocitadlo :zoznam
     urobtu "sucet :hodnota + :sucet
   ]
   urobtu "priemer :sucet / 8

Výpočet súčtu môžeme urýchliť aj príkazom aplikuj "sucet :zoznam

   urobtu "priemer aplikuj "sucet :zoznam / pocet :zoznam

Výpočet jedného hárku papiera:

Na záver ešte potrebujeme priemernú hodnotu meraní predeliť 16timi, keďže sme pre lepšiu presnosť merali hmotnosť 16 papierov naraz a výsledok vypísať do textového poľa.

   vysledok'nechHodnota :priemer / 16

Zhrnutím všetkých možných vylepšení môžeme prekvapujúco dospieť až k takémuto krátkemu zápisu procedúry počítaj:

   viem počítaj
     urobTu "zoznam []
     opakuj 10 [
       urobTu "zoznam vlozPo (vykonaj slovo "meranie pocitadlo) :zoznam
   ]
   urobTu "zoznam bezPr bezPo utried :zoznam
   vysledok'nechHodnota (aplikuj "sucet :zoznam / pocet :zoznam) / 16    koniec

Vaše zaujímavé riešenia:

Viacero tímov použilo správne príkaz utried :zoznam, iný zase hľadali najmenší prvok cez cyklus. Niektoré tímy si vytvorili aj pomocné procedúry, ktoré riešili čiastkové úlohy - nájdi, vymaž, vylúč a podobne. Vyskytlo sa aj jedno riešenie, ktoré najmenší a najväčší prvok zarátalo aj do súčtu, ale na záver ho z toho súčtu (ešte pred vyrátaním priemeru) odrátalo:

  urob "najmensie 1000
  urob "najvacsie 0
  urob "sucet 0
   preprvky "x :zoznam [
     ak(:x < :najmensie)[urob "najmensie :x]
     ak(:x > :najvacsie)[urob "najvacsie :x]
     urob "sucet (:sucet + :x)
   ]
   urob "priemer ((:sucet - :najmensie - :najvacsie) / 8)

Najčastejšie nedostatky:

  • za výsledok ste označili už hmotnosť 16tich hárkov papiera,
  • logické chyby pri hľadaní najmenšieho a najväčšieho prvku v podmienke ak pri používaní príkazov alebo a zaroven,
  • pri riešeniach bez použitia zoznamov ste sa zamotali pri určovaní podmienok,
  • priemer ste vypočítali zo všetkých desiatich meraní.