Cvičenie 3 – Cykly, funkcie, referencie
Cieľom cvičení tretieho týždňa je precvičiť si:
- využitie cyklov,
- metódy vracajúce hodnoty,
- debugovanie (krokovanie) programu.
Archetyp: jpaz2-archetype-quickstart
Na začiatok
- Čo nakreslí nižšie uvedená metóda
mystery
?
Nájdite v tejto metóde miesto, kde sa vytvorí objekt triedy Color
. Koľko parametrov ma použitý konštruktor? Akého typu je premenná c
?
- Do triedy
SmartTurtle
pridajte metódu, ktorá nastaví náhodnú farbu kresliaceho pera.
- Do triedy
SmartTurtle
pridajte metóduconcentricCircles
s parametromradius
, ktorá nakreslí „nekonečnú“ postupnosť vnorených sústredných kruhov. „Nekonečnú“ znamená, že útvary, ktoré nie je vidieť, už nekreslíme. Prvý (najväčší) kruh nech má polomer určený parametromradius
. Každý ďalší (vnorený) kruh, nech má polomer, ktorý je 80% z polomeru toho predošlého. Farby kruhov nech sa postupne cyklicky striedajú: červená, modrá, šedá.
1
2
3 public void concentricCircles(double radius) {
}
- Upravte predošlú metódu tak, aby vrátila súčet obsahov skutočne nakreslených kruhov.
Korytnačie počty
- Vytvorte triedu
ScientificTurtle
rozširujúcu trieduTurtle
s nasledujúcimi metódami:min
vráti menšie z číselcislo1
acislo2
power
vypočíta nkfactorial
vypočítan!
countDivisors
vráti počet prirodzených deliteľov číslan
isPrime
vráti, či je číslon
prvočíslomcountDigits
vráti počet cifier číslan
containsDigit
– vráti, či zápis číslan
obsahuje cifruc
hasNonincreasingDigits
– vráti, či cifry čísla tvoria nerastúcu postupnosť. Cifry čísla 44220 tvoria nerastúcu postupnosť, ale cifry čísla 2231 nie (3 je väčšie ako naľavo od neho nachádzajúca sa cifra 2)gcd
vráti najväčšieho spoločného deliteľa čísela
ab
(neskôr sa naučíme aj efektívny Euklidov algoritmus)lcm
vráti najmenší spoločný násobok čísela
ab
1
2
3
4
5
6
7
8
9
10 public double min(double cislo1, double cislo2)
public long power(int n, int k)
public long factorial(int n)
public int countDivisors(int n)
public int countDigits(int n)
public boolean isPrime(int n)
public boolean containsDigit(byte c, int n)
public boolean hasNonincreasingDigits(int n)
public int gcd(int a, int b)
public int lcm(int a, int b)
- (Povinná úloha): odkrokujte výpočet niektorej z implementovaných metód.
Ďalšie úlohy
- Naučte korytnačky triedy
SmartTurtle
metódusnooker
, ktorá bude realizovať nasledovný algoritmus:- korytnačka príkazom
this.setRangeStyle(RangeStyle.BOUNCE);
nastaví, aby sa odrážala od hranice kresliaceho plátna - korytnačka na náhodných súradniciach nakreslí čierny kruh (dieru) s polomerom 10. X-ová aj Y-ová súradnica kruhu nech je náhodné číslo z intervalu
<20, 280)
(predpokladáme štandardnú kresliacu plochu s rozmermi300 x 300
). - kým sa korytnačka nedostane do vnútra vygenerovaného čierneho kruhu (diery) jej pohyb sa riadi týmito pravidlami:
- každý krok korytnačky je krok aktuálnym smerom dĺžky 3 (za každým krokom pozastavíme program na pár milisekúnd napr. príkazom
JPAZUtilities.delay(50)
) - každých 300 krokov sa korytnačka náhodne otočí
- každý krok korytnačky je krok aktuálnym smerom dĺžky 3 (za každým krokom pozastavíme program na pár milisekúnd napr. príkazom
- korytnačka príkazom
1 public void snooker()
Pre fajnšmekrov
- Do triedy
ScientificTurtle
pridajte metódufindGreatestDigit
, ktorá vráti najväčšiu cifru v zadanom čísle. - Kalkulačka sa nám pokazila a jediné operácie, ktoré dokáže zrealizovať sú pripočítanie jednotky k poslednému výsledku (číslu na displeji) a vynásobenie posledného výsledku dvomi. Na začiatku je na displeji číslo 0. Vytvorte metódu (v triede
ScientificTurtle
), ktorá pre zadané číslo vráti minimálny počet operácii, ktoré musíme vykonať, aby sme na displeji zobrazili parametrom zadané číslon
. - Pomocou obsahu prvých troch týždňov skúste zistiť odpoveď na otázku: „Aká je priemerná vzdialenosť dvoch bodov vo štvorci so stranou dĺžky jedna?“
- Svoju experimentálnu odpoved skúste potvrdiť analyticky (výpočtom).
- Riešenie aj s analyzou https://www.youtube.com/watch?v=i4VqXRRXi68
Math.pow?
Math.pow
je užitočná metóda na vyrátanie mocniny čísla s desatinnou čiarkou. Konkrétne Math.pow(a, b)
vráti ab. Všimnime si však jej hlavičku:
1
Keďže exponent je typu double
, túto metódu môžeme použiť aj na vypočítanie neceločíselných mocnín. Príklad: Math.pow(3.5, 0.25)
vypočíta štvrtú odmocninu z čísla 3.5
.
To, že táto metóda pracuje s číslami s desatinnou čiarkou, je tak jej silnou stránkou, ale pri nevhodnom použití aj slabou stránkou. Totiž čísla s desatinnou čiarkou majú limitovanú presnosť.
Príkladom nevhodného použitia tejto metódy je počítanie celých mocnín celých čísel. Vyskúšajte tento kód (napr. v metóde main
triedy Launcher
):
Na doplnenie: 1315 = 51185893014090757, čo je menej ako maximálna hodnota pre long
9223372036854775807
, t.j. nedôjde tu k pretečeniu (a rozdielnosť hodnôt tak nie je zapríčinená pretečením pri násobení ale limitovanou presnosťou hodnôt typu double
).
Rýchlejší počet deliteľov
Cieľom jednej z úloh bolo pre zadané kladné nenulové číslo n
určiť počet jeho deliteľov. Na prednáške bol prezentovaný jednoduchý algoritmus založený na testovaní všetkých celých čísel od 1
po n
. Zároveň na prednáške bolo naznačené, že si vystačíme aj s testovaním menšieho počtu čísel – konkrétne √n
čísel. Ako však na to?
Uvažujme číslo n
. Nech a
je nejakým deliteľom čísla n
. Potom musí existovať také celé číslo b
, že n = a.b
. Teda číslo b
je taktiež deliteľom čísla n
. Na tieto 2 delitele čísla n
môžeme pozerať ako na akési „kamarátske“ delitele čísla n
. Bez ujmy na všeobecnosti nech a <= b
. Ak a
nie je √n
, potom platí, že a < √n
a b > √n
(dôkaz sporom – ak by a < √n
a b < √n
, potom a.b < √n.√n = n
, čo je v spore, že a.b = n
; analogicky možno dokázať, že nenastane a > √n
a b > √n
). Dôsledkom tohto pozorovania je to, že ku každému deliteľovi ostro menšiemu ako √n
prislúcha jeden deliteľ ostro väčší ako √n
a naopak.
Zvyšok je už len programátorčina…