Download - LOGO Zadaci
-
6 Zadaci
U ovom emo poglavlju rijeiti mnoge zadatke kakvi se pojavljuju na natjecanjima. Detaljno emo opisati kako doi do rjeenja. Objasnit emo i neke poznate algoritme.
6.1 Euklidov algoritam (razlomci)
Zadatak 1 (Euklidov algoritam). Napiite funkciju gcd :a :b koja nalazi najvei zajedniki djelitelj prirodnih brojeva :a i :b.
Primjeri za provjeru:
gcd 5 2 Result: 1
gcd 2 3 Result: 1
gcd 5 10 Result: 5
gcd 20 30 Result: 10
gcd 30 45 Result: 15
gcd 64 48 Result: 16
Rjeenje. Da bismo ovo rijeili, moemo koristiti najstariji poznati algoritam koji potjee jo iz antikih vremena. Jo je Euklid znao da je najvei zajedniki djelitelj brojeva a i b jednak najveem zajednikom djelitelju brojeva a i a b . Tako dolazimo do rjeenja.
to gcd :a :b if :b = 0 op :a op gcd :b remainder :a :b end
Zadatak 2. Napiite funkciju lcm :a :b koja nalazi najmanji zajedniki viekratnik prirodnih brojeva :a i :b.
Primjeri za provjeru:
-
198 LOGO za napredne
lcm 5 2 Result: 10
lcm 2 3 Result: 6
lcm 5 10 Result: 10
lcm 20 30 Result: 60
lcm 30 45 Result: 90
gcd 64 48 Result: 192
Rjeenje. Koristei rjeenje prethodnog zadatka dolazimo do rjeenja:
to lcm :a :b op :a*:b/gcd :a :b end
Zadatak 3. Napiite funkciju skrati :a :b koja skrauje razlomak :a:b
(ako je to mogue) i vraa listu koja se sastoji od dva broja. Prvi broj je brojnik razlomka, a drugi nazivnik.
Na primjer, razlomak 6448 moemo skratiti jer su mu i brojnik i nazivnik djeljivi sa
16 pa imamo 4 643 48
43
= . Stoga bi funkcija skrati 64 48 vratila [4 3].
Parametri :a i :b su prirodni brojevi.
Primjeri za provjeru:
skrati 5 2 Result: [5 2]
skrati 2 3 Result: [2 3]
skrati 5 10 Result: [1 2]
skrati 20 30 Result: [2 3]
lcm 30 45 Result: [2 3]
skrati 64 48 Result: [4 3]
Rjeenje.
to skrati :a :b make "g gcd :a :b op list :a/:g :b/:g end
-
6. Zadaci 199
Zadatak 4. Napiite funkciju zbroji :l1 :l2 koja vraa zbroj dva razlomka :l1 i :l2. Parametri :l1 i :l2 su liste koje se sastoje od dva prirodna broja. Prvi broj svake liste oznaava brojnike, a drugi nazivnike (kao u prethodnom zadatku).
Primjeri za provjeru:
zbroji [1 2] [1 2] Result: [1 1] Jer je
1 1 22 2+ =
211
= (to jest 1).
zbroji [1 2] [1 3] Result: [5 6] Jer je
1 1 2 3 52 3 6 6
++ = = .
zbroji [1 2] [2 1] Result: [5 2] Jer je
1 2 1 4 52 1 2 2
++ = = .
zbroji [1 6] [1 3] Result: [1 2] Jer je
1 1 1 2 36 3 6
++ = =6
12
= .
Rjeenje.
to zbroji :l1 :l2 make "a +(first :l1)*last :l2 (first :l2)*last :l1 make "b *last :l1 last :l2 op skrati :a :b end
Zadatak 5. Napiite funkciju mnozi :l1 :l2 koja vraa umnoak dvaju razlomaka :l1 i :l2. Parametri :l1 i :l2 su liste koje se sastoje od dva prirodna broja. Prvi broj svake liste oznaava brojnike, a drugi nazivnike (kao u prethodnom zadatku).
Primjeri za provjeru:
mnozi [1 2] [1 2] Result: [1 4] Jer je 1 1 12 2 4 = .
mnozi [1 2] [3 1] Result: [3 2] Jer je
1 332 2 = .
-
200 LOGO za napredne
mnozi [1 2] [2 1] Result: [1 1] Jer je
12
2 11
= (to jest 1).
mnozi [5 6] [3 10] Result: [1 4] Jer je
56
310
14
= .
Rjeenje.
to mnozi :l1 :l2 make "a *first :l1 first :l2 make "b *last :l1 last :l2 op skrati :a :b end
6.2 Kutovi U ovom emo odjeljku obraditi neke zadatke za rjeavanje kojih bi bilo dobro najprije malo promozgati o kutovima na slici.
Zadatak 6. Napiite proceduru zvijezda :n :d koja crta zvijezdu sa :n krakova. Svaki vrh je spojen sa 2 nasuprotna vrha (kao na slici 1). Udaljenost nasuprotnih vrhova je :d (kao na slici 1). Kut u vrhu svakog
kraka je 180:n
.
Parametar :n je neparan broj vei od 2, dok je parametar :d broj vei od nule.
Na primjer na slici 1 je nacrtana zvijezda sa 5 krakova. Jedan od moguih naina da se ona nacrta bio bi da se slijede crvene strelice.
Primjeri za provjeru:
cs zvijezda 3 200 cs zvijezda 5 170
1
2
3
45
d
d
Slika 1
-
6. Zadaci 201
cs zvijezda 7 150 cs zvijezda 17 200
Rjeenje.
to zvijezda :n :d repeat :n [fd :d rt 180 - 180/:n] end
Napomena 1*. Ovaj zadatak (injenica da emo ako odaberemo kut od 180n
stupnjeva takvim redosljedom crtanja dobiti zvijezdu) je posljedica jednog poznatog matematikog teorema (teorema o sredinjem i obodnom kutu).
Zadatak 7. Napiite proceduru medalja :n :d :kut koja brie ekran i crta zvijezdu s :n krakova. Kut izmeu svaka dva kraka je isti. Duljina brida svakog kraka je :d. Kut u vrhu svakog kraka je :kut. Na slici 1 je 4=:n i 45=:kut . Parametar :n je prirodni broj vei ili jednak od 3, :d je broj vei od nule. Parametar :kut je broj vei od nule, a manji od 180.
Primjeri za provjeru:
medalja 4 90 60 medalja 5 120 30 medalja 12 100 20
Rjeenje. Bilo bi dobro prvo ustanoviti koliki je kut izmeu svaka dva kraka (na slici 2 kut ). U tu svrhu pogledajmo malo bolje neki krak (na slici 3 jedan krak je zatamnjen). To je u
45
d
Slika 2
Slika 3
-
202 LOGO za napredne
stvari jednakokrani trokut, a u svakom trokutu je zbroj svih kutova 180. Iz toga
dobijemo 180
2 = . Budui da nadopunjene (isprekidane) linije ine pravilni
mnogokut, vrijedi 360 = :n . Iz toga se napokon dobije 2 360 + + = (jer
ine puni kut). Napokon dobijemo 360180 = +:n :kut .
Sada vie nije teko napraviti program koji crta traeni lik.
to medalja :n :d :kut cs make "g_d 180-360/:n+:kut repeat :n [fd :d rt 180-:kut fd :d lt 180-:g_d] end
Jedno malo drugaije rjeenje moglo bi biti:
to medalja :n :d :kut repeat :n [fd :d lt :kut bk :d rt :kut] end
Zadatak 8. Napiite proceduru most :s :d :v koja crta lik kao na slici 4. Lik predstavlja most koji se sastoji od etiri stepenice visine i irine :s i jednog luka. Luk se sastoji od sedam paralelograma sa stranicama duljine :d i :v. Kut izmeu brida prvog paralelograma i horizontale je 30, dok je svakog sljedeeg za 10 manji (pa su bridovi sredinjeg paralelograma paralelni s rubovima ekrana). Lik je simetrian obzirom na sredinji paralelogram.
Parametri :s, :d i :v su brojevi vei od nule.
Primjeri za provjeru:
cs most 20 20 10 cs most 25 10 100
cs rt 30 most 15 25 75 cs most 15 15 75
30s
dd
v
Slika 4
-
6. Zadaci 203
Rjeenje.
to paralelogram :v :d :k fd :v rt 90-:k fd :d rt 90+:k fd :v rt 90-:k fd :d bk :d rt 90+:k end
to most :s :d :v seth 0 repeat 4 [fd :s rt 90 fd :s lt 90]
(for "i 30 -30 [ paralelogram :v :d :i] -10) rt 90 repeat 4 [fd :s rt 90 fd :s lt 90] end
Zadatak 9. Napiite proceduru cvijet :d :m :n koja crta :n :m-terokuta (zovimo ih latice), koji se dodiruju vrhovima. Kutovi izmeu najbliih stranica susjednih latica meusobno su jednaki (na slici 5 kut ) i takvi da se prva i posljednja latica takoer dodiruju (tako da sve latice ine cvijet u obliku kruga).
Ako je broj :m neparan, tada latica (:m-terokut) ima jednu stranicu vie okrenutu prema vanjskoj strani cvijeta (kojeg ine tih :n latica). Na slici 5 2 su stranice okrenute prema unutra, a 3 prema van. (Na slici 5 je primjer za
5=:m i 8=:n .) Ako je broj :m paran, tada jednak broj stranica mora biti okrenut prema unutranjoj kao i prema vanjskoj strani.
Parametar :d je broj vei od nule. Parametar :m je prirodan broj vei od 2, a :n prirodan broj vei od 1.
Primjeri za provjeru:
cs cvijet 150 3 2 cs cvijet 100 4 4
cs cvijet 60 4 7 cs cvijet 50 6 6
d
d
Slika 5
-
204 LOGO za napredne
cs cvijet 20 9 10 cs cvijet 20 16 6
Rjeenje.
to latica :d :m repeat :m[fd :d lt 360/:m] make "i 0 repeat :m/2[fd :d lt 360/:m make "i :i+1] rt :i*360/:m end
to cvijet :d :m :n repeat :n[latica :d :m rt 360/:n] end
Zadatak 10. Napiite proceduru atom :n :d :m :r koja crta atom kao na slici 6. Atom se sastoji od :n elektrona. Sredite slike predstavlja jezgru atoma, a vanjski :m-terokuti elektrone. Elektroni su u pravilnom odnosu s jezgrinom spojnicom (na slici 6 jednak je kut na obje strane kut ). Elektroni su pravilno rasporeeni oko jezgre tako da je kut izmeu svaka dva susjedna elektrona jednak . Na slici 6 je primjer kada je :n = 3, a :m = 4.
Parametri :d i :r su brojevi vei od nule, dok su :m i :n prirodni brojevi vei od dva.
Primjeri za provjeru:
cs atom 5 100 3 100 cs atom 8 100 4 70
cs atom 12 100 3 100 cs atom 6 100 36 5
Rjeenje.
to elektron :m :a lt 90-180/:m repeat :m[fd :a rt 360/:m]
d
r
Slika 6
-
6. Zadaci 205
rt 90-180/:m end
to atom :n :d :m :a repeat :n[fd :d elektron :m :a bk :d rt 360 /:n] end
Zadatak 11. Napiite proceduru sito :d :k :m :n koja crta mreu od :n vodoravnih redova. Svaki se red sastoji od :m pravilnih :k-terokuta duljine stranice :d. Svaka dva susjedna :k-terokuta dodiruju se ili samo vrhom ili samo jednom stranicom. (Svaki :k-terokut je zrcalna slika susjeda s obzirom na paralelu s rubovima ekrana na slici 7 isprekidane linije).
Na slici 7 je primjer za 5=:k , 4=:m , 3=:n . Neki :k-terokuti su osjenani
zbog lakeg uoavanja.
Parametar :d je broj vei od nule. Parametar :k je prirodan broj vei od 2, dok su :m i :n prirodni brojevi.
Primjeri za provjeru:
cs sito 180 3 1 1 cs sito 100 4 2 2
cs sito 70 3 4 1 cs sito 50 3 1 5
cs sito 50 5 4 3 cs sito 20 6 7 4
cs sito 20 8 5 5 cs sito 5 36 5 4
Rjeenje.
to jedan pd repeat :k[fd :d lt 360/:k] pu repeat 1+2*int (:k-1)/4[fd :d lt 360/:k] setheading 0-heading rt 180-360/:k end
to medjured1 if :k>4 [repeat (:k-1)/4[rt 360/:k bk :d]]
Slika 7
-
206 LOGO za napredne
rt 180+360/:k end
to medjured2 repeat (:k+1)/4[fd :d lt 360/:k] setheading 180-heading rt 180-360/:k repeat (:k-1)/2[fd :d lt 360/:k] end
to medjured lt 180-360/:k setheading 0-heading if (remainder :i 2)=1 [medjured1] else [medjured2] end
to red if :k>4 [repeat (:k-1)/4[rt 360/:k bk :d]] repeat :m [jedan] medjured end
to sito :d :k :m :n rt 90 for "i 1 :n [red] end
Zadatak 12. Napiite proceduru sunce koja brie ekran i crta lik kao na slici 8. Sunce je kosi kvadrat sa stranicama duljine 60. Iz svake stranice izlaze po dvije zrake koje tu stranicu dijele na jednake dijelove (duljine 20). Iz svakog vrha izlazi po jedna zraka (koja je paralelna s rubom ekrana). Svake dvije susjedne zrake zatvaraju jednak kut. Duljina svake zrake je 90.
Rjeenje. Najprije odredimo kut izmeu svake dvije zrake. Uoimo prije da imamo ukupno 12 zraka. Produimo li zrake u unutranjost kvadrata (kao na slici 9), uoavamo da je kut izmeu
90
90
90
60
60 20
Slika 8
-
6. Zadaci 207
svake dvije zrake jednak 360 /12 30= (jer se crtanjem svih krakova rotiramo za cijeli krug). Mogli bismo imati varijablu u kojoj pamtimo smjer zrake (varijabla z) te varijablu u kojoj pamtimo smjer crtanja sredita (kvadrata; varijabla k). Ponimo od lijeve vodoravne zrake.
to sunce cs make "z -90 make "k 45 repeat 4[repeat 3 [seth :z fd 90 bk 90 seth :k fd 20 make "z :z+30] make "k :k+90] end
Zadatak 13. Napiite proceduru sunce :d :n :l :r koja crta :n-terokut duljine stranice :d. Iz svake stranice :n-terokuta prema van ide odreeni broj linija (zovimo ih zrake). Te zrake dijele stranicu na dijelove jednakih duljina (na slici 10 duljine duine x). Duljina srednje zrake je :l i okomita je na stranicu. Svaka sljedea zraka od srednje prema vrhu kraa je za :r i zakoena za isti kut u odnosu na prethodnu zraku (kutovi izmeu susjednih zraka su isti na slici 10 kut ). Posljednja je zraka ona kojoj je duljina manja od :r i vea ili jednaka nuli. Ona je u vrhu :n-terokuta.
Kut je takav da se posljednja zraka jedne stranice poklapa sa prvom zrakom susjedne stranice (samo jedna zraka ide iz vrha :n-terokuta).
Na slici 10 je primjer za 4=:n , 44=:l i 12=:r . Duljine zraka su redom 44, 32, 20 i 8. Iz toga slijedi da je na svakoj stranici 7 zraka te je x
6=:d , a 15 = .
Parametri :d i :l su brojevi vei od nule. Parametar :r je broj vei od nule i manji od :l, dok je parametar :n je prirodan broj vei od 2.
44 - = 32 r32 - = 20
r
d x
x 44
Slika 10
Slika 9
-
208 LOGO za napredne
Primjeri za provjeru:
cs sunce 100 3 150 60 cs sunce 50 4 44 12
cs sunce 70 5 150 10 cs sunce 20 7 150 11
cs sunce 30 7 150 3 cs sunce 5 36 100 40
Rjeenje.
to zraka :i lt 90-:g_a*:i fd :l-:r*abs :i bk :l-:r*abs :i rt 90-:g_a*:i end
to zrake for "i 1 2*:broj_zraka [fd :x zraka :i-:broj_zraka] end
to sunce :d :n :l :r make "broj_zraka int :l/:r make "g_a 360 / :n / (2*:broj_zraka) make "x :d/(2*:broj_zraka) repeat :n[zrake rt 360/:n] end
Zadatak 14. Napiite proceduru valjak :v :d :n koja crta valjak (tonije prizmu) visine :v. Baza valjka je pravilni :n-terokut sa stranicama duljine :d. Baza je u pravilnom odnosu s bonim bridovima (kutovi baze s oba brida su jednaki na slici 11 oznaeni s ). Da bi se dobio dojam tree dimenzije, jedna se baza u potpunosti vidi, dok je druga nacrtana samo do pola (na slici 11 donja polovica :n-terokuta).
Na slici 11 je primjer kada :n ima vrijednost 6.
-
6. Zadaci 209
Parametar :n je paran prirodni broj vei od 3, dok su parametri :v i :d brojevi vei od nule.
Primjeri za provjeru:
cs valjak 120 100 4 cs valjak 100 50 10 cs valjak 100 70 6 cs valjak 20 10 36 cs valjak 120 10 36
Rjeenje.
to valjak :v :d :n bk :v lt 180/:n repeat :n/2 [bk :d lt 360/:n] seth 0 fd :v lt 180/:n repeat :n[fd :d lt 360/:n] end
Zadatak 15. Napiite proceduru valjak :v :d :n koja crta lik kao na slici 12. Parametri :v, :d i :n su isti kao u prethodnom zadatku.
Primjeri za provjeru: Budui da je zadatak vrlo slian prethodnom, isti primjeri mogu posluiti.
Rjeenje.
to valjak :v :d :n make "kut 180-180/:n for "i 1 :n/2 [seth 0 fd :v bk :v seth :kut fd :d make "kut :kut-360/:n] seth 0 fd :v lt 180/:n repeat :n[fd:d lt 360/:n] end
v
d
Slika 11
v
d
Slika 12
-
210 LOGO za napredne
Zadatak 16. Napiite proceduru kap :n :d koja brie ekran i crta lik kao na slici 13. Lik se sastoji od :n stranica pravilnog mnogokuta s 2 ( 1) :n vrhova. Lik se sastoji od jo dvije stranice (koje su jednako dugake kao i irina lika na slici desno varijabla r).
Na slici desno je primjer kada :n ima vrijednost 5.
Parametar :n je prirodan broj vei od 2, dok je parametar :d broj vei od nule. Parametri :n i :d su takvi da lik ne prelazi rubove ekrana.
Primjeri za provjeru:
kap 3 100 kap 4 70
kap 4 70 kap 30 10
Rjeenje.
to kap :n :d cs bk :d repeat :n-1 [lt 180/(:n-1) bk :d] make "r xcor rt 150 fd :r lt 120 fd :r end
Zadatak 17. Napiite proceduru lopta :d :s :alfa koja brie ekran i crta putanju lopte koja se odbija od tla. Tlo je horizontalna linija na sredini ekrana. Lopta je izbijena iz sredine ekrana pod kutom :alfa u odnosu na horizontalu brzinom :d. Kada doe do tla odbija pod istim kutom kojim je nabijena, ali je brzina za varijablu :s manja nego kod izbijanja. Odbijanje se nastavlja tako dugo dok je brzina odbijanja vea od
r
rr
d
d
d
Slika 13
d
d - s
Srediteekrana
Slika 14
-
6. Zadaci 211
nule. Na slici 14 je primjer lopta 150 50 60.
Parametri :d i :s su brojevi vei od nule. Parametar :alfa je broj vei od nule i manji od 90.
Primjeri za provjeru:
lopta 150 100 60 lopta 100 100 30
lopta 200 10 87 lopta 100 200 20
Rjeenje.
to odbij :d :beta rt :beta fd :d lt 2*:beta bk :d rt :beta end
to lopta :d :s :alfa cs (for "i :d 0 [odbij :i 90-:alfa] 0-:s) end
6.3 Koordinatna grafika
Zadatak 18. Napiite funkciju teziste :a :b :c koja brie ekran i crta trokut zajedno s njegovim teinicama. Parametri :a, :b i :c su dvolane liste koje oznaavaju koordinate vrhova A, B i C. (Oni su takvi da te toke ne prelaze rubove ekrana). Funkcija vraa koordinate teita nacrtanog trokuta.
Primjeri za provjeru:
teziste [-150 100] [200 100] [50 -100] Result: [33.33 33.33]
teziste [-200 200] [200 200] [-200 -200] Result: [-66.67 66.67]
( , )A AA x y ( , )B BB x y
( , )C CC x y
Slika 15
-
212 LOGO za napredne
teziste [-150 100] [50 100] [150 -100] Result: [16.67 33.33]
Rjeenje.
to teziste :a :b :c cs pu setxy :a pd setxy :b setxy :c setxy :a
setxy list / + first :b first :c 2 (/ + last :b last :c 2)
pu setxy :b pd setxy list / + first :a first :c 2 (/ + last :a last :c 2)
pu setxy :c pd setxy list / + first :b first :a 2 (/ + last :b last :a 2) pu
op list (+ first :a first :b first :c)/3 (+last :a last :b last :c)/3 end
Zadatak 19. Napiite proceduru kvadrati :d :n koja crta :n kvadrata upisanih jedan u drugi. Duljina stranice poetnog kvadrata je :d. Stranice poetnog kvadrata su paralelne s rubovima ekrana. Sredite (sjecite dijagonala isprekidane linije na slici 16) kvadrata je na sredini ekrana. Vrhovi svakog sljedeeg kvadrata su na polovitima stranica prethodnog (kao na slici 16 za
4=:n ). Parametar :d je broj vei od nule, a manji od 400. Parametar :n je prirodan broj.
Primjeri za provjeru:
cs kvadrati 200 1 cs kvadrati 200 3
cs kvadrati 300 5 cs kvadrati 256 6
d
d
Srediteekrana
Slika 16
-
6. Zadaci 213
Rjeenje.
to kosi_kvadrati :d :n pu setxy se 0 :d pd setxy se :d 0 setxy se 0 0-:d setxy se 0-:d 0 setxy se 0 :d kvadrati :d :n-1 end
to kvadrati :d :n if :n = 0 stop make "d :d/2 pu setxy se :d :d pd setxy se :d 0-:d setxy se 0-:d 0-:d setxy se 0-:d :d setxy se :d :d if :n > 1 kosi_kvadrati :d :n-1 end
Zadatak 20: Napiite proceduru sat :h :m :s koja crta sat koji pokazuje zadano vrijeme. Kazaljka za minute treba pratiti kazaljku za sekunde, a kazaljka za sate onu za minute slika se bitno razlikuje za vrijeme 1 : 00 : 00 i 1 : 59 : 59 . Sat se sastoji od krunice. Svaka minuta je oznaena crticom duljine 3, svaki sat linijom duljine 5, a svaka tri sata linijom duljine 10. Na slici 17 je primjer za sat 2 59 41.
Parametar :h oznaava sate, :m minute, a :s sekunde.
Rjeenje. Ovaj zadatak bi se mogao rijeiti i bez koordinatne grafike, ali ga neemo tako rijeiti. Koordinatne funkcije emo koristiti za crtanje krunice.
to sat :h :m :s cs make "vrhovi array 60
Slika 17
-
214 LOGO za napredne
U varijablu vrhovi zapamtiti emo toke na krunici polumjera 100 sa sreditem u ishoditu (da bi ju kasnije mogli nacrtati).
for "i 0 59 [pu home seth :i*6 fd 94 pd fd 3 pu fd 3 aset :vrhovi :i getxy]
Nacrtali smo crtice za minute te zapamtili vrhove na krunici polumjera 94 3 3 100+ + = . Nakon toga crtamo crtice za sate:
for "i 0 11 [pu home seth :i*30 fd 92 pd fd 5]
i vee crtice za svaka 3 sata:
for "i 0 3 [pu home seth :i*90 fd 90 pd fd 10]
Nakon toga crtamo krunicu polumjera 100 kroz zapamene vrhove:
pu setxy aget :vrhovi 59 pd for "i 0 59 [setxy aget :vrhovi :i]
i krunicu polumjera 100/ 20 5= (koja je u sreditu sata). pu setxy list / first aget :vrhovi 59 20 (/ last
aget :vrhovi 59 20) pd for "i 0 59 [setxy list / first aget :vrhovi :i 20 (/ last aget :vrhovi :i 20)]
Zatim crtamo kazaljku za sekunde. Kod svih nam kazaljki treba fd 5 kako ne bismo sjekli krunicu u sreditu sata.
pu home seth :s * 6 fd 5 pd fd 85
Crtanje kazaljke za minute:
pu home make "m1 :m + :s / 60 seth :m1 * 6 fd 5 pd repeat 2 [lt 3 fd 43 rt 6 fd 43 rt 177]
I na kraju nacrtamo kazaljku za sate:
pu home seth (:h + :m1 / 60) * 30 fd 5 pd lt 30 fd 10 rt 35 fd 57 lt 10 bk 57 rt 35 bk 10 lt 30 end
-
6. Zadaci 215
Zadatak 21. Napiite proceduru zvijezda :n :d koja brie ekran i crta :n jednakih jednakokranih trokuta koji se dodiruju vrhovima suprotnim osnovici (kao na slici 18). Duljina kraka je :d. Kut izmeu svaka dva trokuta je jednak (na slici 18 kut ) i dvostruko je vei od kuta izmeu krakova trokuta (na slici desno kut ). Na slici 18 je primjer kada je 3=:n . Parametar :n je prirodan broj vei od jedan, dok je :d broj vei od nule i manji ili jednak od 200 (tako da lik ne prelazi rubove ekrana).
Toka u kojoj se dodiruju trokuti je na sredini ekrana.
Primjeri za provjeru:
zvijezda 7 200 zvijezda 4 200
zvijezda 6 100 zvijezda 15 150
Rjeenje.
to zvijezda :n :d cs make "l [] repeat :n [fd :d make "l lput getxy :l bk :d rt 120/:n fd :d make "l lput getxy :l bk :d rt 240/:n]
for "i 1 :n[pu setxy item :i*2-1 :l pd setxy item :i*2 :l] end
Zadatak 22. Napiite proceduru sunce :n :h :v koja brie ekran i crta lik kao na slici 19. Lik predstavlja sunce (koje je u sreditu ekrana) iz kojeg izlazi :n zraka ravnomjerno rasporeenih (kut izmeu svake dvije susjedne zrake je jednak). Zrake dodiruju bridove zamiljenog pravokutnika sa stranicama
v
h
Srediteekrana
Slika 19
dSrediteekrana
Slika 18
-
216 LOGO za napredne
:h i :v kojemu je sjecite dijagonala u sreditu ekrana.
Parametar :n je prirodan broj. Parametar :h je broj vei od nule i manji od 640, dok je parametar :v broj vei od nule i manji od 480 (tako da zamiljeni pravokutnik ne prelazi rubove ekrana).
Na slici 19 je primjer kada :n ima vrijednost 7.
Primjeri za provjeru:
sunce 5 300 100 sunce 16 400 200
sunce 18 300 300 sunce 35 600 300
Rjeenje.
to zraka :h :v while [and (and (xcor = 0-:h)) (and (ycor = 0-:v))] [fd 1] end
to sunce :n :h :v cs for "i 1 :n [home seth 360*:i/:n zraka :h/2 :v/2] end
Zadatak 23. Napiite proceduru cvijet :d :n koja brie ekran i crta :n rombova od kojih svaka dva susjedna imaju jednu zajedniku stranicu. Svi rombovi imaju zajedniki vrh u sreditu ekrana. Rombovi su ravnomjerno rasporeeni (kao na slici 20) tako da zatvaraju puni kut. Oko slike je opisan pravokutnik koji dodiruje vrhove nekih rombova i ne sijee niti jednu stranicu. Na slici 20 je primjer kada :n ima vrijednost 9.
Parametar :n je prirodan broj vei od dva. Parametar :d je broj manji od 100 (tako da lik ne prelazi rubove ekrana).
Rjeenje. Sljedei kd crta sm cvijet:
to romb :d :alfa
d
d
Srediteekrana
Slika 20
-
6. Zadaci 217
fd :d rt :alfa fd :d rt 180-:alfa fd :d rt :alfa fd :d rt 180 end
to cvijet :n :d cs repeat :n [romb :d 360/:n] end
Jo ostaje problem kako nacrtati pravokutnik koji opisuje lik. Budui da lik nee prelaziti rubove ekrana, dobro bi bilo nakon svake nacrtane linije promatrati trenutne koordinate kornjae, zapamtiti najgornju, najdonju, najljeviju i najdesniju toku te na kraju nacrtati taj pravokutnik. (Uoimo da nije dovoljno promatrati koordinate samo nakon nacrtanog drugog brida romba jer bi se u sluaju :n 3= dobila loa slika.)
to pozicija if xcor
-
218 LOGO za napredne
repeat :n [romb :d 360/:n] pravokutnik end
Zadatak 24. Napiite proceduru luk :n :a :b koja brie ekran i crta luk koji se sastoji od :n jednakih jednakokranih trapeza koji se dodiruju krakovima. (Na slici 21 je jednakokrani trapez). Krakovi trapeza su duljine :b, dok je duljina krae osnovice jednaka :a. Svaka dva susjedna trapeza meusobno zatvaraju jednak kut
(na slici 22 kut ), dok su vanjski krakovi (na slici 22 tamnije osjenani krakovi) rubnih trapeza (unutranjosti su im ispunjene) paralelni sa donjim rubom ekrana. Na slici 22 je primjer kada je 4.=:n Parametar :n je prirodan broj, a parametri :d i :a su brojevi vei od nule.
Parametri su tako odabrani tako da lik ne prelazi rubove ekrana!
Sredite ekrana je na sredini horizontalne duine (na slici 22 isprekidana linija) koja spaja dva horizontalna kraka rubnih trapeza (kao na slici 22).
Rjeenje. Uoimo da bi bilo dobro prvo odrediti koliki su nam kutovi i . Oito vrijedi 2 360 + = , jer ti kutovi zatvaraju puni kut. Odredimo kut . Ako malo bolje promotrimo, krae osnovice trapeza ine polovicu pravilnog mnogokuta sa
2:n vrhova (slika 23). Zbog toga vrijedi 360 =2
180= :n:n . Odatle slijedi 90180 = :n .
Dulja osnovica
bb
a
osnovicaKraa
Kra
k Krak
Slika 21
Srediteekrana
bb
b
a
a
Slika 22
-
6. Zadaci 219
Ostaje nam jo samo odrediti koliko se moramo pomaknuti ulijevo (nai koliki je d) tako da nam lik bude na sredini ekrana. Zbog toga se pomaknimo ulijevo koliko moemo (u stvari bi pozicija ( 300,0) bila sasvim dobra). Nacrtajmo pola tog mnogokuta i pogledajmo kolika nam je x-koordinata. Iz toga dobijemo
3002
d += XCOR .
Obriimo ekran, pomaknimo se na poziciju ( ,0)d , rotirajmo se ulijevo za pravi kut i nacrtajmo jedan krak trapeza. Sada jo samo treba nacrtati trapez :n puta. Naalost, ne znamo duljinu due osnovice trapeza (na slici 24 isprekidane crte). Dodue to nam i nije
toliko bitno jer se moemo posluiti sljedeim trikom: Moemo crtati lik bez duljih osnovica trapeza, a pamtiti koordinate krajeva krakova (na slici 24 su zaokrueni). Na kraju samo te toke spojimo linijama.
Napiimo dakle program:
to sirina :n :a pu make "g_b 180/:n seth :g_b/2 setx -300 repeat :n [fd :a rt :g_b] pd op (xcor+300)/2 end
Slika 24
/2
d
Slika 23
-
220 LOGO za napredne
to luk :n :a :b make "g_a 90+90/:n make "d sirina :n :a pu cs setx 0-:d lt 90 pd fd :b make "l (list getxy) repeat :n [bk :b rt :g_a fd :a lt 180-:g_a fd :b make "l lput getxy :l] (for "i (count :l)-1 1 [setxy item :i :l] -1) end
Zadatak 25. Napiite proceduru peretak :m :r :n :d koja brie ekran i crta lik kao na slici 25. Lik se sastoji od po jedne polovine dva pravilna :m-terokuta. Manjem :m-terokutu su vrhovi udaljeni za :r od sredita ekrana, a veem za a+:r (a je duljina najdulje dijagonale pravilnog :n-terokuta). U jednom rubnom vrhu lika je pravilni :n-terokut sa stranicama duljine :d, dok je u svim ostalim vrhovima pola pravilnog :n-terokuta. Rubni su vrhovi svake polovine pravilnog :n-terokuta zajedniki s vrhovima pravilnih :m-terokuta. (Na slici 25 je primjer kada :m ima vrijednost 6, a :n 8.)
Parametri :m i :n su parni brojevi, dok su :d i :r su brojevi vei od nule (i takvi da lik ne prelazi rubove ekrana).
Primjeri za provjeru:
peretak 6 100 8 50 peretak 10 100 36 7
peretak 8 100 2 100 peretak 36 150 36 5
peretak 16 50 16 30 peretak 16 50 4 70
Rjeenje.
to peretak :m :r :n :d pu home rt 180/:n repeat :n/2 [fd :d rt 360/:n] make "a xcor cs
r d
r
Slika 25
-
6. Zadaci 221
make "mu [] make "mv []
for "i 0 :m/2 [home seth 180*:i/(:m/2)-90 fd :r make "mu lput getxy :mu fd :a make "mv lput getxy :mv]
for "i 0 :m/2 [pu home seth 180*:i/(:m/2)-90 fd :r pd lt 90-180/:n repeat :n/2[fd :d rt 360/:n]]
repeat :n/2[fd :d rt 360/:n]
pu setxy first :mv pd for "i 1 count :mv [setxy item :i :mv]
pu setxy first :mu pd for "i 1 count :mu [setxy item :i :mu] end
Zadatak 26. Napiite proceduru dija :n :d koja brie ekran i crta mnogokut s :n stranica duljine :d kao na slici 26. Svi vrhovi mnogokuta su spojeni linijama s prvim vrhom.
Parametar :n je prirodni broj vei od 2, a :d je broj vei od nule. Parametri :n i :d imaju takve vrijednosti da mnogokut ne prelazi granica ekrana.
Primjeri za provjeru:
dija 3 100 dija 10 70 dija 15 50 dija 36 20
Rjeenje.
to dija :n :d cs for "i 2 :n-1 [repeat :i [fd :d rt 360/:n] home] end
d
Slika 26
-
222 LOGO za napredne
Zadatak 27. Napiite proceduru dija :n :d koja brie ekran i crta mnogokut s :n stranica duljine :d kao na slici. Svaki vrh mnogokuta je spojen sa svim ostalim vrhovima.
Parametar :n je prirodni broj vei od 2, a :d je broj vei od nule. Parametri :n i :d imaju takve vrijednosti da mnogokut ne prelazi granica ekrana.
dija 3 100 dija 4 100 dija 5 100 dija 10 70 dija 15 50
Rjeenje.
to dija :n :d cs make "vrhovi array :n for "i 0 :n-1[fd:d rt 360/:n aset :vrhovi :i getxy]
for "i 0 :n-2 [for "j :i+1 :n-1 [ pu setxy aget :vrhovi:i pd setxy aget:vrhovi :j]]
end
Zadatak 28. Napiite proceduru upisuj :n :d :k koja crta :k pravilnih :n-terokuta upisanih jedan u drugi. Udaljenost vrhova vanjskog :n-terokuta do sredita ekrana je :d (kao na slici 28). Vrhovi sljedeeg :n-terokuta su na polovitima stranica prethodnog. Na slici 28 je primjer za
5=:n , 2=:k . Parametar :n je prirodan broj vei od 2. Parametar :d je broj vei od nule, a parametar :k je prirodan broj.
d d
Srediteekrana
Slika 28
d
Slika 27
-
6. Zadaci 223
Parametri :n i :d su takvi da lik na prelazi rubove ekrana.
Primjeri za provjeru:
cs upisuj 4 150 5 cs upisuj 3 100 4
cs upisuj 5 150 3 cs upisuj 6 150 3
cs upisuj 10 100 5 cs upisuj 36 100 10
Rjeenje. Prvo emo zapamtiti koordinate vrhova :n-terokuta (funkcija nadji_vrhove). Duinama poveemo sve te toke (procedura crtaj). Nakon toga naemo polovita tih duina (koja znamo izraunati po formulama iz
drugog poglavlja 2
A BP
x xx += , 2
A BP
y yy += funkcija pola, nadji_polovista). Postupak ponovimo (:k puta) s dobivenim tokama.
to nadji_vrhove :n :d make "l [] pu home repeat:n[fd:d make "l lput getxy:l bk :d rt 360/:n] op :l end
to crtaj :l pu setxy last :l pd for "i 1 count :l [setxy item :i :l] end
to pola :l1 :l2 op se ((item 1 :l1)+(item 1 :l2))/2 ((item 2 :l1)+(item 2 :l2))/2 end
to nadji_polovista :l make "l1 (list pola first :l last :l) for "i 2 count :l [make "l1 lput (pola item :i-1 :l item :i :l) :l1] op :l1 end
to upisuj :n :d :k make "kordinate nadji_vrhove :n :d repeat :k [crtaj :l make "l nadji_polovista :l] end
-
224 LOGO za napredne
Zadatak 29. Napiite proceduru elipsa :n :a :b koja brie ekran i crta elipsu. Parametar :a odreuje irinu elipse, dok je :b visina elipse. Elipsu dobijemo tako da pravilni :n-terokut malo suzimo ili rairimo.
Parametar :a je broj manji od 600, a :b broj manji od 400 (pa elipsa ne prelazi rubove ekrana). Parametar :n je prirodni broj vei od dva.
Primjeri za provjeru:
elipsa 3 200 200 elipsa 15 300 300
elipsa 3 400 200 elipsa 36 300 300
elipsa 7 400 250 elipsa 36 400 200
elipsa 8 300 300 elipsa 36 100 300
Rjeenje. Zapamtimo prvo koordinate vrhova nekog pravilnog :n-terokuta koji ne prelazi rubove ekrana. Uzmimo, na primjer, da mu je polumjer 100. Naemo visinu (razlika visina najvieg i najnieg vrha) i irinu (razlika irina najdesnijeg i najlijevijeg vrha) :n-terokuta. Prvu koordinatu svakog vrha pomnoimo sa :a i podijelimo sa irinom :n-terokuta (tako e irina novonastalog lika biti jednaka upravo :a). Isto napravimo i s visinom. Spojimo sve toke, i to je to!
to elipsa :n :a :b make "vrhovi array :n cs pu for "i 0 :n-1 [home rt 360*:i/:n fd 100 aset :vrhovi :i getxy]
make "min_x 0 for "i 0 :n-1 [if :min_x>first aget :vrhovi :i make "min_x first aget :vrhovi :i]
make "max_x 0 for "i 0 :n-1 [if :max_x
-
6. Zadaci 225
make "min_y 0 for "i 0 :n-1 [if :min_y>last aget :vrhovi :i make "min_y last aget :vrhovi :i]
make "max_y 0 for "i 0 :n-1 [if :max_y
-
226 LOGO za napredne
cs pu for "i 0 :n-1 [home rt 360*:i/:n fd 100 aset :vrhovi :i getxy]
make "mnozi_x :a/200 make "mnozi_y :b/200
for "i 0 :n-1 [aset :vrhovi :i list :mnozi_x*first aget :vrhovi :i :mnozi_y*last aget :vrhovi :i]
setxy aget :vrhovi :n-1 pd for "i 0 :n-1 [setxy aget :vrhovi :i] end
Zadatak 31. Napiite proceduru elipsa :alfa :n :a :b koja brie ekran i crta elipsu. Parametri :a i :b su kao na slici 30. Elipsu dobijemo tako da pravilni :n-terokut malo suzimo ili rairimo. Parametar :alfa je broj koji odreuje rotaciju elipse u odnosu na rubove ekrana.
Parametri :a i :b su brojevi manji od 400 (tako da elipsa ne prelazi rubove ekrana). Parametar :n je prirodni broj vei od dva.
Primjeri za provjeru:
elipsa 45 3 200 200 elipsa 150 15 300 200
elipsa 45 3 300 200 elipsa 60 36 200 300
elipsa 30 7 300 250 elipsa 20 36 350 200
elipsa 90 8 300 300 elipsa 70 36 100 300
Rjeenje. Rjeenje je slino crtanju obine elipse, ostaje nam jo rotacija. Nakon to smo izraunali koordinate svih toaka, prije crtanja izraunamo koordinate toaka rotirane elipse. Njih raunamo funkcijom rotacija.
a
b
Slika 30
-
6. Zadaci 227
to rotacija :alfa :l home rt :alfa + towards :l fd sqrt (* first :l first :l) + (* last :l last :l) op getxy end
Sredite rotacije je ishodite koordinatnog sustava. Kut do toke ( , )x y odredimo funkcijom towards. Udaljenost d ishodita do toke ( , )x y je 2 2x y+ . Koordinate rotirane toke dobijemo tako da gledamo u smjeru zbroja kutova i te se pomaknemo naprijed za d (kao na slici 31).
to elipsa :n :a :b make "vrhovi array :n cs pu for "i 0 :n-1 [home rt 360*:i/:n fd 100 aset :vrhovi :i getxy]
make "min_x 0 for "i 0 :n-1 [if :min_x>first aget :vrhovi :i make "min_x first aget :vrhovi :i]
make "max_x 0 for "i 0 :n-1 [if :max_x
-
228 LOGO za napredne
for "i 0 :n-1 [aset :vrhovi :i rotacija :alfa aget :vrhovi :i]
setxy aget :vrhovi :n-1 pd for "i 0 :n-1 [setxy aget :vrhovi :i] end
Zadatak 32. Napiite proceduru brod :n :d :x koja brie ekran i crta val na kojemu je brod. Val se sastoji od jednog brijega i jednog dola. I brijeg i dol su polovice 2:n -terokuta sa stranicama duljine :d. Brod se nalazi na udaljenosti :x od poetka vala. Na valu je i jednako je rotiran kao val.
Na slici 32 vidimo primjer kada :n ima vrijednost 3.
Parametar :n je prirodan broj vei od jedan, dok je parametar :d prirodan broj takav da lik ne prelazi rubove ekrana. Parametar :x je broj takav da se brod sigurno nalazi na valu.
Primjeri za provjeru (vidimo i pripadne slike):
brod 36 5 45
brod 36 6 135
brod 36 6 235
Rjeenje.
to brodic fd 15 lt 60 fd 10 lt 120 fd 15 rt 90 fd 5 lt 90 fd 5 lt 90 fd 5 rt 90 fd 5 lt 120 fd 10 lt 60 end
xd
Slika 32
-
6. Zadaci 229
to _fd :n :x repeat :n[fd 1 if and(:brod_nacrtan="FALSE) (xcor=:x) [brodic make "brod_nacrtan "TRUE]] end
to brod :n :d :x make "brod_nacrtan "FALSE cs rt 90/:n repeat :n [_fd :d :x rt 180/:n] repeat :n [lt 180/:n _fd :d :x] end
Zadatak 33. Napiite proceduru cijev :v :d :alfa koja brie ekran i crta cijev visine :v i putanju loptice kroz cijev (kao na slici 33). Cijev je poloena vodoravno. Poetak putanje loptice je na lijevom kraju donje stijenke cijevi i pod :alfa stupnjeva u odnosu na vertikalu. Put koji loptica prevali je :d toaka. irina cijevi je jednaka x-koordinati zadnje pozicije loptice.
Parametri :v i :d su brojevi vei od nule. Parametar :alfa je broj vei od nule i manji od 90. Parametri su takvi da lik ne prelazi rubove ekrana.
Primjeri za provjeru:
cijev 100 200 45 cijev 100 300 45
cijev 100 300 60 cijev 100 500 30
cijev 100 100 60 cijev 10 500 30
Rjeenje.
to _fd :v :alfa fd :smjer if and ycor>=:v :smjer=1 make "smjer -1 lt 2*:alfa if and ycor
-
230 LOGO za napredne
make "smjer 1 repeat round :d [_fd :v :alfa]
make "s xcor pu sety 0 pd home pu sety :v pd setx :s end
Zadatak 34. Napiite proceduru cijev :h :d :alfa koja brie ekran i crta lik kao na slici 34. Zadatak je isti kao prethodni, s razlikom da je cijev poloena vertikalno.
Primjeri za provjeru:
cijev 100 200 45 cijev 100 300 45 cijev 100 400 60 cijev 100 250 30 cijev 150 250 10 cijev 150 50 45
Rjeenje.
to _fd :h :alfa fd 1 if and xcor>=:h :smjer=1 make "smjer -1 lt 2*:alfa if and xcor
-
6. Zadaci 231
stranicama duljine :a i :b) i putanju biljarske kugle. Kugla se poinje gibati iz sredita ekrana pod kutom :alfa, a :d je duljina koju kugla prelazi. Bilijar ne prelazi rubove ekrana.
Parametar :alfa je cijeli broj.
Primjeri za testiranje:
bilijar 300 200 45 2000 bilijar 300 200 30 2000 bilijar 200 200 60 1000 bilijar 300 100 20 500 bilijar 100 200 60 300 bilijar 100 100 70 300
Rjeenje.
to fd1 :x :y fd 1 if or (xcor>=:x) (xcor=:y) (ycor
-
232 LOGO za napredne
Primjeri za testiranje:
bilijar 100 45 60 100 bilijar 100 45 60 500 bilijar 70 30 60 500 bilijar 70 70 10 500 bilijar 90 70 10 500
Rjeenje. Za rjeavanje ovog zadatka potrebno nam je poznavanje analitike geometrije. Nakon podueg teorijskog razmatranja dolazimo do funkcije koja odreuje nalaze li se dvije toke s iste strane pravca:
to ispod :p1 :p2 :t1 :t2 make "dx (first :p1) - (first :p2) make "dy (last :p1) - (last :p2)
make "c1 ((first :t1) - (first :p1))*:dy - ((last :t1) - (last :p1))*:dx
make "c2 ((first :t2) - (first :p1))*:dy - ((last :t2) - (last :p1))*:dx
op (:c1 * :c2) > 0 end
Dakle toke su sa iste strane ako varijable 1c i 2c imaju isti predznak. Sada jo moramo utvrditi kako rijeiti odbijanja:
to fd1 :p :beta fd 1
if or (not ispod item 1 :p item 2 :p [0 0] getxy) (not ispod item 3 :p item 4 :p [0 0] getxy) [seth 180-(heading-2*:beta)]
if or (not ispod item 2 :p item 3 :p [0 0] getxy) (not ispod item 4 :p item 1 :p [0 0] getxy) [seth 0-(heading-2*:beta)] end
a
Slika 36
-
6. Zadaci 233
to biljar :a :beta :alfa :d cs pu seth :beta make "p [] repeat 4 [fd :a make "p lput getxy :p bk :a rt 90] setxy last :p pd for "i 1 4 [setxy item :i :p] pu home seth :alfa pd repeat :d [fd1 :p :beta+45] end
6.4 Dubina slike (trea dimenzija)
Zadatak 37. Napiite proceduru kvadar :a :b :c :m :n :k :alfa koja crta kvadar sa stranicama :a, :b i :c. Kut izmeu stranica :a i :c je pravi, a kut izmeu stranica :b i :c je :alfa. Brid :a je podijeljen na :m jednakih dijelova, brid :b na :n jednakih dijelova, dok je brid :c je podijeljen na :k jednakih dijelova.
Parametri :a, :b i :c su brojevi vei od nule, dok su :m, :n i :k prirodni brojevi. Parametar :alfa je broj vei od 0, a manji od 90.
Primjeri za provjeru:
cs kvadar 100 70 100 1 1 1 60
cs kvadar 100 70 150 1 1 1 45
cs kvadar 100 70 150 2 3 4 45
cs kvadar 200 70 150 5 3 4 30
cs kvadar 250 50 150 5 3 8 30
b
a
c
Slika 37
-
234 LOGO za napredne
Rjeenje.
to mreza :a :b :m :n :kut repeat :m+1[rt:kut pd fd:b bk:b lt:kut pu fd:a/:m] bk :a+:a/:m repeat :n+1 [pd fd:a bk:a rt:kut pu fd:b/:n lt kut] rt :kut bk :b/:n lt :kut end
to kvadar :a :b :c :m :n :k :alfa mreza :c :a :k :m 90 mreza :c :b :k :n :alfa fd :c lt 180-:alfa mreza :b :a :n :m 90-:alfa end
Zadatak 38. Napiite proceduru piramida :n :d :alfa :v koja brie ekran i crta lik kao na slici desno.
Parametar :n je prirodni broj, dok su :n i :v brojevi. Parametar :alfa je broj vei od nule i manji od 90.
Rjeenje.
to cigla :d repeat 4 [fd :d rt 90] rt 90 fd :d lt 90 end
to zid :n :d repeat :n [cigla :d] fd :d lt 90 fd :n*:d bk :d/2 rt 90 end
to piramida :n :d :alfa :v cs (for "i :n 1 [zid :i :d] -1) lt 90 fd :d/2 rt 90 rt :alfa fd :v rt 90-:alfa fd :d/2 repeat :n [fd :d/2 rt 90 rt :alfa fd :v bk :v lt :alfa fd :d rt :alfa fd :v bk :v lt :alfa lt 90] end
d
v
Slika 38
-
6. Zadaci 235
Zadatak 39. Napiite proceduru kocke :a :b :alfa :v koja brie ekran i crta dvije kocke (kvadra) kao na slici 39. Manja kocka je dvostruko kraih bridova i treba biti na sredini gornje plohe vee kocke.
Parametri :a, :b i :v su brojevi vei od nule, dok je :alfa broj vei od nule i manji od 90.
Primjeri za provjeru:
kocke 50 50 45 50 kocke 70 100 30 50 kocke 50 100 75 40
Rjeenje. Za razliku od prethodnog zadatka (gdje trea dimenzija nije bila potpuna lijevi rubovi slike) ovdje emo to napraviti pravilno. Procedura paralelogram crta paralelogram i brie njegovu unutranjost. Dakle prvo crtano veu kocku, a nakon toga, prilikom crtanja manje, briemo nepotrebne crtice (koje se nalaze iza male kocke pa se ne bi trebale vidjeti).
to paralelogram :a :b :kut rt 90-:kut if 0=int :a go "crtaj_paralelogram
pe repeat int :a[rt :kut fd :b bk :b lt :kut fd 1] bk int :a pd
label "crtaj_paralelogram repeat 2 [fd :a rt :kut fd :b rt 180-:kut] lt 90-:kut end
to kocka :a :b :alfa :v paralelogram :a :b 90 fd :a paralelogram :v :b 90-:alfa bk :a pu rt 90 fd :b lt 90 lt 90-:alfa pd paralelogram :a :v :alfa pu rt 90-:alfa rt 90 bk :b lt 90 pd end
to kocke :a :b :alfa :v cs kocka :a :b :alfa :v
a
b
v
Slika 39
-
236 LOGO za napredne
pu fd :a rt 90 fd :b/4 lt 90-:alfa fd :v/4 lt :alfa pd kocka :a/2 :b/2 :alfa :v/2 end
Zadatak 40. Napiite proceduru kocke :a :b :alfa :v :n koja brie ekran i crta :n kocaka. Kocke se nalaze jedna na drugoj (kao i prethodnom zadatku). Donja je kocka najvea, a svaka sljedea dvostruko je kraih bridova.
Parametri :a, :b i :v su brojevi vei od nule, dok je :alfa broj vei od nule i manji od 90. Parametar :n je prirodni broj.
Primjeri za provjeru:
kocke 50 50 45 50 3 kocke 70 100 30 50 4 kocke 50 100 75 40 5
Rjeenje.
to paralelogram :a :b :kut rt 90-:kut if 0=int :a go "crtaj_paralelogram
pe repeat int :a[rt :kut fd :b bk :b lt :kut fd 1] bk int :a pd
label "crtaj_paralelogram repeat 2 [fd :a rt :kut fd :b rt 180-:kut] lt 90-:kut end
to kocka :a :b :alfa :v paralelogram :a :b 90 fd :a paralelogram :v :b 90-:alfa bk :a pu rt 90 fd :b lt 90 lt 90-:alfa pd paralelogram :a :v :alfa pu rt 90-:alfa rt 90 bk :b lt 90
fd :a rt 90 fd :b/4 lt 90-:alfa fd :v/4 lt :alfa pd end
-
6. Zadaci 237
to kocke :a :b :alfa :v :n cs (for "i :n 1 [kocka :a :b :alfa :v make "a :a/2 make "b :b/2 make "v :v/2] -1) end
Zadatak 41. Napiite proceduru hanoi :n :a :b :v koja crta lik kao na slici 40. Parametar :n je prirodni broj koji odreuje broj diskova, :a je irina najveeg diska, :b njegova dubina, a :v visina.
Primjeri za provjeru:
hanoi 1 200 100 30 hanoi 2 200 100 30 hanoi 5 100 50 10
Rjeenje. Da pojednostavimo rjeenje, koristit emo naredbe stampoval i stamprect. Rjeenje se temelji na tome da nacrtamo :n diskova. Disk crtamo tako da obriemo dio ekrana na kojem emo nacrtati disk (naredbe stampoval i stamprect u zagradama). Nacrtamo cijelu donju elipsu, prebriemo dio koji se ne treba vidjeti, nacrtamo vertikalne rubove i gornju elipsu.
to disc :a :b :v pd setpc 0 (stampoval :a/2 :b/2 "true) setpc 15 stampoval :a/2 :b/2 setpc 0 pu lt 90 fd :a/2 pd (stamprect :a :v "true)
setpc 15 rt 90 fd :v pu rt 90 fd :a pd rt 90 fd :v bk :v rt 90 pu fd :a/2 rt 90 pd
setpc 0 (stampoval :a/2 :b/2 "true) setpc 15 stampoval :a/2 :b/2 end
to hanoi :n :a :b :v cs (for "i :n 1 [disc :a*i/:n :b*:i/n :v] -1) end
Slika 40
-
238 LOGO za napredne
6.5 Ispunjavanje zatvorene povrine bojom (FILL)
Moda ste se nekad zapitali kako radi naredba fill, odnosno kako je mogue neko podruje ispuniti odreenom bojom. To bi mogli tako da krenemo od neke toke ( , )x y unutar tog podruja. Provjerimo sa dotcolor trebamo li tu toku obojiti (boja joj je crna?). Ako trebamo, nacrtamo toku (naredba dot) te isti postupak ponovoimo (rekurzivno) s 4 susjedne toke s koordinatama ( 1, )x y+ , ( 1, )x y , ( , 1)x y + , ( , 1)x y . I to je to!
Zadatak 42. Napiite proceduru ispuni :x :y koja ispunjava povrinu oko toke sa koordinatama :x i :y bojom.
Primjeri za provjeru:
cs repeat 3 [fd 20 rt 120] ispuni 1 2 cs repeat 6 [fd 10 rt 60] ispuni 1 0 cs repeat 12[fd 7 re 30] ispuni 1 0
Rjeenje.
to ispuni :x :y if not 0=dotcolor se :x :y stop dot se :x*100 :y*100 ispuni :x+1 :y ispuni :x-1 :y ispuni :x :y+1 ispuni :x :y-1 end
Napomena 2. Vidimo da je ovo rjeenje dosta sporo, a troi i puno memorije (za bilo koji vei lik nam se napuni stog te dobijemo pogreku) jer nam je uvjet rekurzije zadovoljen previe puta (postupak crtanja je skiciran je na slici 41). Rekurzija poziva samu sebe sve dok ne naie da zatvoreno podruje (kako vidimo na slici, dugo nee naii na zatvoreno podruje).
Taj bismo zadatak mogli rijeiti i malo pametnije. Mogli bi se istovremeno kretati u
Nekakav rub
Nek
akav
rub
( , )x y
Slika 41
-
6. Zadaci 239
sva etiri smjera, a u listu pamtiti na koja mjesta jo trebamo doi. Trenutno mjesto uzimamo s poetka liste, a nove (etiri) toke na koje emo doi ubacujemo na kraj liste (takav se pristup u programiranju naziva queue).
to ispuni :x :y make "l (list se :x :y) while [not empty? :l][(if 0=dotcolor first :l [ make "x first first :l make "y last first :l dot se :x*100 :y*100 make "l lput se :x+1 :y :l make "l lput se :x-1 :y :l make "l lput se :x :y+1 :l make "l lput se :x :y-1 :l ]) make "l bf :l] end
Ovo rjeenje radi s dosta veim podrujima, ali radi dosta sporo (lista nam postaje velika pa naredbe bf, lput sporo rade). Postupak bismo mogli ubrzati tako da umjesto liste upotrijebimo neki veliki niz. Varijabla p simulira poetak, a varijabla z kraj liste. Ubacivanje elementa na kraj liste bilo bi uveavanje varijable z za jedan, a izbacivanje s poetka, uveavanje varijable p za jedan. Moramo biti oprezni da se, ako doemo do kraja niza, vratimo na poetak (funkcija remainder). Lista je prazna kada se varijable p i z poklope (dakako, ako smo uzeli dovoljno velik niz).
to ispuni :x :y make "d 5000 make "l array :d make "p 0 make "z 0 aset :l :z se :x :y make "z :z+1 while [not :p = :z][(if 0=dotcolor aget :l :p[ make "x first aget :l :p make "y last aget :l :p dot se :x*100 :y*100 aset :l :z se :x+1 :y make "z remainder :z+1 :d aset :l :z se :x-1 :y make "z remainder :z+1 :d aset :l :z se :x :y+1 make "z remainder :z+1 :d aset :l :z se :x :y-1 make "z remainder :z+1 :d ]) make "p remainder :p+1 :d] end
Zadatak 43. Napiite proceduru hrv :l1 :l2 koja brie ekran i crta lik odreen tokama iz liste :l1 plavom bojom. Lista :l1 se sastoji od dvolanih lista (svaka odreuje poziciju na ekranu). Nakon toga ispunite taj lik crvenim i bijelim tokicama (jedna crvena, jedna bijela, kao na hrvatskom grbu),
-
240 LOGO za napredne
ali tako da toka koju odreuje lista :l2 bude obojena bijelom bojom. Toka :l2 bit e sigurno u unutranjosti lika, a lik e se uvijek sastojati od jednog dijela (nee biti presijecanja ni dodirivanja linija).
Na slici 42 je primjer kada je :l1 jednako [[0 0] [2 0] [4 2] [4 6] [-2 6] [-2 2]], a :l2 je [0 1].
Na slici 43 je primjer kada je :l1 jednako [[0 0] [8 0] [8 10] [11 7] [14 10] [7 17] [1 17] [-6 10] [-3 7] [0 10]], a :l2 je jednako [4 11]. Strjelicom je oznaeno u kojem smjeru crtamo plavi rub, a toka :l2 je uokvirena.
Rjeenje. Najprije crtamo rub lika (plavom bojom broj 9). Rjeenje je je slino obinom ispunjavanju, ali u ovom sluaju mijenjamo boje crvenu (broj 4) i bijelu (broj 15).
to ispuni :x :y :b if not 0=dotcolor se :x :y stop
setpc :b dot se :x*100 :y*100 if :b = 15 make "b 4 else make "b 15
ispuni :x+1 :y :b ispuni :x-1 :y :b ispuni :x :y-1 :b ispuni :x :y+1 :b end
to hrv :l1 :l2 cs setpc 9 pu setxy last :l1 pd for "i 1 count :l1 [setxy item :i :l1] ispuni first :l2 last :l2 15 end
(0,0) (2,0)(0,1)
(4, 2)
(4,6)( 2,6)-
( 2, 2)-
Slika 42
Slika 43
-
6. Zadaci 241
6.6 Zadaci s brojevima
Zadatak 44. Napiite funckiju najmanji :l koja vraa najmanji element liste :l. Lista :l sastoji se od brojeva (bar jednog).
Primjeri za provjeru:
najmanji [1] Result: 1
najmanji [0 1 2 0] Result: 0
najmanji [1 2 3] Result: 1
najmanji [4 4 4] Result: 4
najmanji [3 4 1 0] Result: 0
najmanji [1 2 4 -5] Result: -5
Rjeenje.
to najmanji :l make "m first :l for "i 2 count :l [if (item :i :l) < :m make "m item :i :l] op :m end
Zadatak 45. Napiite funkciju najveci :l koja vraa najvei element liste :l. Lista :l sastoji se od brojeva (bar jednog).
Primjeri za provjeru:
najveci [1] Result: 1
najveci [0 1 2 0] Result: 2
najveci [1 2 3] Result: 3
najveci [4 4 4] Result: 4
najveci [3 4 1 0] Result: 4
najveci [1 2 4 -5] Result: 4
-
242 LOGO za napredne
Rjeenje.
to najmanji :l make "m first :l for "i 2 count :l [if (item :i :l) < :m make "m item :i :l] op :m end
Zadatak 46. Napiite funkciju srednja_vrijednost :l koja vraa srednju vrijednost liste :l. Srednja vrijednost liste definira se kao zbroj svih njezinih lanova podijeljen s brojem lanova liste.
Lista :l se sastoji od brojeva (bar jednog).
Primjeri za provjeru:
srednja_vrijednost [1 2 3] Result: 2
srednja_vrijednost [1 1] Result: 1
srednja_vrijednost [2 3] Result: 2.5
srednja_vrijednost [4 5 12] Result: 7
Rjeenje.
to srednja_vrijednost :l make "s 0 for "i 1 count :l [make "s :s + item :i :l] op :s / count :l end
6.6.1 Prosti brojevi
Zadatak 47. Napiite funkciju PROST :n koja nalazi najmanji prost broj vei ili jednak od :n.
:n je prirodan broj manji od 10 000.
Primjeri za provjeru:
-
6. Zadaci 243
pr prost 7 7 Jer je broj 7 prosti broj!
show prost 1 2 Jer broj 1 nije prost po definiciji, a 2 je!
prost 8 Result: 11 Jer brojevi 8, 9 i 10 nisu prosti, a 11 je!
prost 15 Result: 17 Jer brojevi 15 i 16 nisu prosti, a 17 je!
prost 140 Result: 149
Jer brojevi 140148 nisu prosti, a 149 je!
prost 9999 Result: 10007
Jer brojevi 9 99910 006 nisu prosti, a 10 007 je!
Rjeenje.
to is_prost :n if :n=1 op "false for "i 2 :n-1 [if 0=remainder :n :i op "false] op "true end
to prost :n make "p :n while [not is_prost :p] [make "p :p+1] op :p end
Zadatak 48. Napiite proceduru rastavi :n koja rastavlja prirodan broj :n na proste faktore. (Npr. prosti faktori broja 15 su 3 i 5, jer su 3 i 5 prosti brojevi i vrijedi 15 3 5= , dok su prosti faktori broja 24 redom 2, 2, 2 i 3, jer su 2 i 3 prosti i vrijedi 24 2 2 2 3= .) Primjeri za provjeru:
rastavi 15 3 5
rastavi 12 2 2 3
-
244 LOGO za napredne
Rjeenje. Prvo rjeenje koje nam pada na pamet, je da broj :n dijelimo sa svim prostim brojevima kojima moemo, i tako sve dok ne dobijemo broj 1. Koristei rjeenje prethodnog zadataka, dobivamo rjeenje:
to rastavi :n make "d 2 while [:n>1][if 0=remainder:n:d pr:d make"n :n/:d else make "d prost :d+1] end
Napomena 3*. Prethodni zadatak mogao bi se rijeiti jednostavnije. Uoite da nema potrebe provjeravati je li odreeni djelitelj :d prost broj. Jer ako :d nije prost, s njim nee biti mogue dijeliti broj :n (jer smo ga ve podijelili sa svim brojevima manjim od :d pa i sa djeliteljima od :d). Uoivi taj detalj, dobivamo bolje rjeenje:
to rastavi :n make "d 2 while [:n>1][if 0=remainder :n :d pr:d make"n :n/:d else make "d :d+1] end
6.6.2 Eratostenovo sito
U mnogim problemima (pogotovo u matematici) esto trebamo (vie puta u istom problemu) sve proste brojeve manje od nekog broja n. Da ne bi svaki puta utvrivali da li je broj prost i traili sljedei vei, objasniti emo jednu jako staru metodu. Ideje je u tome da prvo uzmemo skup prvih n brojeva (1, 2, 3, 4, 1n , n). Iz njega izbacimo broj 1 (jer on po definiciji nije prost).
Iz toga skupa izbacimo sve viekratnike broja 2 (4, 6, 8, 10, 12, ) jer oni sigurno nisu prosti (budui da su djeljivi sa 2). Nakon toga izbacujemo sve viekratnike broja 3 (6, 9, 12, 15, ), ni oni nisu prosti (budui da su djeljivi sa 3).
Broj 4 se ne nalazi u skupu (budui da smo ga izbacili kad smo izbacivali viekratnike broja 2). Zbog toga nema potrebe izbacivati viekratnike broja 4 (8, 12, 16, ), oni su ve izbaeni (jer su bili viekratnici broja 2).
Izbacujemo sve viekratnike broja 5 (10, 15, 20, ). Broj 6 nije u skupu (jer je bio viekratnik brojeva 2 i 3). Pa znamo da smo ve izbacili i sve viekratnike broja 6
Zadatak 49. Napiite funkciju eratosten :n koja vraa niz byteova od :n elemenata. Na i-tom mjestu toga niza nalazi se 1 ako je i prost broj, a 0 inae.
-
6. Zadaci 245
Primjeri za provjeru:
make "a eratosten 100 aget :a 90 Result: 0
aget :a 3 Result: 1
aget :a 15 Result: 0
aget :a 7 Result: 1
aget :a 4 Result: 0
aget :a 21 Result: 0
aget :a 23 Result: 1
Rjeenje.
to eratosten :n make "a bytearray :n+1 for "i 2 :n [aset :a :i 1] aset :a 0 0 aset :a 1 0 for "i 2 :n[if 1=aget :a :i (for "j 2*:i :n[aset :a :j 0] :i)]
op :a end
Napomena 4*. Ovaj bi algoritam mogao biti i puno efikasniji. Evo breg rjeenja:
to eratosten :n make "a bytearray :n+1 for "i 2 :n [aset :a :i 1] aset :a 0 0 aset :a 1 0
(for "i 4 :n [aset :a :i 0] 2)
make "i 3 while [:i*:i
-
246 LOGO za napredne
6.6.3 Veliki brojevi
U ovom emo poglavlju raditi s velikim prirodnim brojevima. Tu mislim na prirodne brojeve koji su vei od npr. 10 znamenaka pa Logo kod njih gubi zadnje znamenke. Mi to ne elimo, nego elimo s njima raditi s maksimalnom tonou. Velike brojeve emo zapisivati na dva naina. Zbog jednostavnosti emo ih zapisivati kao rijei koje poinju slovom D iza kojeg slijedi niz znamenaka koje ine broj. Na primjer broj 123 emo zapisivati sa "D123. Taj tip broja zvat emo DBROJ. Ovako se lako uoi o kojem se broju radi, ali bi rad s takvim brojevima bio malo kompliciraniji, pa emo zbog toga uvesti jo jedan tip velikog broja. Nazovimo ga LBROJ. To e u stvari biti lista znamenaka tog broja. Dakle, broj 123 bi bio [1 2 3]. Na taj nain moemo raditi sa puno veim brojevima.
Zadatak 50. Napiite funkciju br2l :b koja broj :b pretvara u LBROJ; l2d :l koja LBROJ :l pretvara u DBROJ i d2l :d koja DBROJ :d pretvara u LBROJ.
Primjeri za provjeru:
br2l 123 Result: [1 2 3]
br2l 2579 Result: [2 5 7 9]
l2d [1 2 5 7 8 9 0 1 2 4 6 8 9 6] Result: D12578901246896
l2d br2l 15623 Result: D15623
d2l "d1250973456893745698712348907 Result: [1 2 5 0 9 7 3 4 5 6 8 9 3 7 4 5 6 9 8 7 1 2 3 4 8 9 0 7]
l2d d2l "d28970938762345243598723405234987 Result: D28970938762345243598723405234987
Rjeenje.
to br2l :b (local "l "l1) if (:b=0) then op [0] make "l [] while [:b>0] [make "l1 remainder :b 10 make "l fput :l1 :l make "b (:b-:l1)/10] op :l end
-
6. Zadaci 247
to l2d :l (local "d "i) make "d "d for "i 1 count :l [make "d lput (item :i :l) :d] op :d end
to d2l :d (local "l "i) make "l [] for "i 2 count :d[make "l lput (abs item :i :d) :l] op :l end
Zadatak 51. Napiite funkciju zbroj :l1 :l2 koja vraa zbroj LBROJEVA :l1 i :l2.
Primjeri za provjeru:
zbroj [1 1 1] [1 2] Result: [1 2 3]
zbroj [1 1 1] [0 1 2] Result: [1 2 3]
zbroj [9 9 9] [1] Result: [1 0 0 0]
zbroj [1] [9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9] Result: [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Rjeenje. Prvo se sjetimo kako zbrajamo brojeve na papiru. Imamo dva broja. Znamenku po znamenku, poevi od zadnje, zbrajamo. Od tog broja gledamo ostatak pri djeljenju sa 10, i piemo ga ispod. Zbroj znamenaka sada dijelimo sa deset, a rezultat dodajemo sljedeim znamenkama (ona mala jedinica).
U rjeenju zadatka varijabla a prati taj prijenos na sljedeu znamenku. Budui da ne moraju oba broja biti iste duljine, potrebna nam je funkcija min :a :b koja vraa manji od ta dva broja.
to min :a :b if :a < :b then op :a op :b end
1 1 1 1 1
9 9 5 8 72 5 6 7 8
1 2 5 2 6 5
+
-
248 LOGO za napredne
U funkciji zbroj rauna se prvo zbroj na dijelu na kojem oba broja imaju znamenaka pa onda samo ostali dio od dueg broja (to smo mogli rijeiti i tako da kraem broju dodamo odgovarajui broj nula na poetak). I na kraju provjeravamo da li je jo jedinica prenesena iz prethodnog rauna te, ako je, dodamo ju.
Lokalne varijable koristimo ,zbog toga to emo ovu funkciju koristiti i prilikom mnoenja, da ne bi dolo do pogreaka.
to zbroj :l1 :l2 (local "l "a "c1 "c2 "i) make "l [] make "a 0 make "c1 count :l1 make "c2 count :l2
for "i 0 (min :c1 :c2)-1 [make "a :a+(item :c1-:i :l1)+(item :c2-:i :l2) make "l fput (remainder :a 10) :l make "a (:a-remainder :a 10)/10]
if (:c1>:c2) then [for "i :c2 :c1-1 [make "a :a+(item :c1-:i :l1) make "l fput (remainder :a 10) :l make "a (:a-remainder :a 10)/10]]]
if (:c2>:c1) then [for "i :c1 :c2-1 [make "a :a+(item :c2-:i :l2) make "l fput (remainder :a 10) :l make "a (:a-remainder :a 10)/10]]]
if (:a>0) then [make "l fput :a :l]
op :l end
Zadatak 52. Napiite funkciju mnoziLB :l :b koja mnoi LBROJ :l i prirodni broj :b (koji nije jako velik 5000< ). Dakle, treba napraviti funkciju koja mnoi veliki broj s malim brojem.
Primjeri za provjeru:
mnoziLB [1 2 3] 1 Result: [1 2 3]
-
6. Zadaci 249
mnoziLB [1 2 3] 2 Result: [2 4 6]
mnoziLB [4 5 6] 789 Result: [3 5 9 7 8 4]
mnoziLB [9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6] 999 Result: [9 0 0 3 3 3 3 3 3 3 2 2 2 3 3 3 3 2 5 4 4]
Rjeenje. Sjetimo se sada i kako se mnoe brojevi na papiru. Neka nam je drugi broj 10< . Gledamo prvi broj od natrag pa, znamenku po znamenku, mnoimo s drugim brojem. Od tog broja gledamo ostatak pri dijeljenju sa 10 pa ga piemo ispod. Opet umnoak dijelimo sa deset i rezultat dodajemo slijedeem umnoku.
U rjeenju zadatka nije toliko bitno da drugi broj bude manji od 10, nego da taj broj pomnoen sa 10 moe stati u normalni broj, a broj 5000 svakako moe. Varijabla a pamti prijenos na sljedei umnoak. U FOR-petlji mnoi se znamenka po znamenka. Na kraju je potrebna WHILE-petlja, jer prijenos (varijabla a) moe biti vea od 10.
to mnoziLB :l :b if (:b=0) op [0] (local "l1 "a "c "i) make "l1 [] make "a 0 make "c count :l
for "i 0 :c-1 [make "a :a+(item :c-:i :l)*:b make "l1 fput (remainder :a 10) :l1 make "a (:a-remainder :a 10)/10]]
while [:a>0] [make "l1 fput (remainder :a 10) :l1 make "a (:a-remainder :a 10)/10]
op :l1 end
Zadatak 53. Napiite funkciju mnoziLL :l1 :l2 koja mnoi LBROJEVE :l1 i :l2. Dakle treba napraviti program koji mnoi dva velika broja.
Primjeri za provjeru:
3 4 5 5 2 15 6 7 8 3 2 7
3 9 7 4 8 2 4
-
250 LOGO za napredne
mnoziLL [1 2 3] [1] Result: [1 2 3]
mnoziLL [1 2 3] [2] Result: [2 4 6]
mnoziLL [4 5 6] [7 8 9] Result: [3 5 9 7 8 4]
mnoziLL [9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] [9 9 9] Result: [9 0 0 3 3 3 3 3 3 3 2 2 2 3 3 3 2 6 5 5]
mnozill [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] Result: [9 9 9 9 9 9 9 9 9 8 0 0 0 0 0 0 0 0 0 1]
Rjeenje. Uzmemo prvu znamenku drugog broja i s njom pomnoimo prvi broj. Rezultat pomnoimo sa 10 (dodavanje nule na kraj liste). Nakon toga mnoimo drugom znamenkom drugog, a rezultat dodamo prolom umnoku. Opet mnoimo sa deset i tako sve dok ne doemo do kraja drugog broja. Moda se ovo ini nekako suprotno onome to smo uili u koli, ali je jednostavnije za programiranje upravo zbog toga dodavanja nule na kraj liste. (Kad koso zbrajamo 68 886 i 61 232, to je u stvari normalan zbroj brojeva 688 860 i 61 232. Dobijemo rjeenje 750 092, dopiemo nulu na kraj i zbrojimo sa 53 578. Dobijemo 7 554 498. Dopiemo nulu i dodamo 45 924 pa dobivamo 75 590 904, to je rjeenje).
to mnozill :l1 :l2 (local "l "i) make "l [] for "i 1 count :l2 [make "l zbroj (lput 0 :l) (mnoziLB :l1 (item :i :l2))] op :l end
Napomena 5. Postoje i puno bolji (bri) algoritmi za mnoenje brojeva, ali budui da se oni ne rade u osnovnoj koli, zadrati emo se na ovom osnovnom kojega su svi, vjerujem, savladali jo u niim razredima.
Zadatak 54. Napiite funkciju faktor :n koji vraa faktorjel prirodnog broja :n. Broj :n je 100< . Faktorjel broja :n jednak je umnoku svih prirodnih brojeva manjih ili jednakih od :n.
7 6 5 4 9 8 7 6
6 8 8 8 66 1 2 3 2
5 3 5 7 84 5 9 2 4
7 5 5 9 0 9 0 4
+
-
6. Zadaci 251
Primjeri za provjeru:
faktor 5 Result: [1 2 0]
faktor 10 Result: [3 6 2 8 8 0 0]
faktor 18 Result: [6 4 0 2 3 7 3 7 0 5 7 2 8 0 0 0]
faktor 30 Result: [2 6 5 2 5 2 8 5 9 8 1 2 1 9 1 0 5 8 6 3 6 3 0 8 4 8 0 0 0 0 0 0 0]
Rjeenje.
to faktor :n (local "i "l) make "l [1] for "i 2 :n [make "l mnoziLB :l :i] op :l end
Zadatak 55. Napiite funkciju expnL :x :n koja vraa :n:x . Parametri :x i :n su prirodni brojevi manji od tisuu, a rjeenje treba biti LBROJ.
Primjeri za provjeru:
expnL 3 3 Result: [2 7]
expnL 5 3 Result: [1 2 5]
expnL 7 10 Result: [2 8 2 4 7 5 2 4 9]
expnL 2 16 Result: [6 5 5 3 6]
expnL 13 13 Result: [3 0 2 8 7 5 1 0 6 5 9 2 2 5 3]
Rjeenje.
to expnL :x :n (local "l "i) make "l [1]
-
252 LOGO za napredne
for "i 1 :n [make "l mnoziLB :l :x] op :l end
Napomena 6. I ovaj zadatak mogli smo uinkovitije rijeiti koristei metodu binarnog potenciranja (opisanu u prethodnom poglavlju):
to expnL :x :n if (:n = 0) op [1] local "l
if (remainder :n 2) = 0 [make "l expnL :x :n / 2 op mnoziLL :l :l]
make "l expnL :x (:n - 1) / 2 op mnoziLB (mnoziLL :l :l) :x end
6.7 Sortiranje
Zadatak 56. Napiite proceduru poredaj :a :b :c koja ispisuje brojeve :a, :b i :c, ali tako da prvo ispie najmanji broj, pa drugi po veliini i tek na kraju najvei broj.
Primjeri za provjeru:
poredaj 1 2 3 1 2 3
poredaj 3 2 1 1 2 3
poredaj 1 2 1 1 1 2
poredaj 1 2 -3 -3 1 2
poredaj 1 1 1 1 1 1
poredaj 1 0 4 0 1 4
Rjeenje.
to poredaj :a :b :c if :a
-
6. Zadaci 253
else [if :a
-
254 LOGO za napredne
6.8 ifriranje (Kriptografija) Postoje brojne metode ifriranja. Od pradavnih vremena postojala je elja da nekome poaljemo poruku koju nitko drugi nemoe saznati. Tijekom vremena, metode su se razvijale.
ifriranje je krojilo tijek povijesti (pogotovo u ratovima). Dananje metode ifriranja vrlo su sloene, ali mi emo obraditi najjednostavnije.
Zadatak 58. Napiite funkciju sifriraj :t :n koja vraa ifrirani tekst :t uz pomo kljua :k. Parametar :t je rije koja se sastoji samo od znakova AZ (njih ukupno 26). Svakom od tih 26 slova pridruimo broj od 0 do 25 ( A 0= , B 1= , ..., Z 25= ). ifrirani tekst se takoer sastoji od slova AZ. Slovo ifriranog teksta dobijemo tako da vrijednosti slova :t dodamo prirodni broj :n. Ako je dobiveni broj vei od 25, umanjimo ga za 26.
Primjeri ifriranja:
:T = ABCD = 0 1 2 3, :n = 4 Rezultat = EFGH = 4 5 6 7
:T = KORNJACA = 10 14 17 13 9 0 2 0, :n = 10 Rezultat = UYBXTKMK = 20 24 1 23 19 10 12 10
Primjeri za provjeru:
sifriraj "abcd 1 Result: BCDE
sifriraj "logo 26 Result: LOGO
sifriraj "sifriranje 3 Result: VLIULUDQMH
Rjeenje. Vrijednost broja moemo dobiti funkcijom ascii. Funkcija za slovo A vrati 65, za B 66, , a za Z 90. Dakle od vrijednosti funkcije ascii oduzmemo broj 65 i dobit emo vrijednost kakva se trai u zadatku. (Analogno onome to dobijemo dodamo broj 65 i to nam je parametar funkcije char.) Toj vrijednosti dodamo broj :n. Budui da taj zbroj moe biti vei od 25 (dakle vei od slova Z, trebamo promatrati ostatak pri dijeljenju sa 26).
to sifriraj :t :n make "rj " for "i 1 count :t [make "rj lput char 65+ remainder ((ascii item :i :t)-65+:n) 26 :rj]
-
6. Zadaci 255
op :rj end
Zadatak 59. Napiite funkciju desifriraj :t :n koja vraa deifrirani tekst :t uz pomo broja :n (iz prethodnog zadatka).
Primjeri za provjeru:
desifriraj "bcde 1 Result: ABCD
desifriraj "logo 26 Result: LOGO
desifriraj "uybxtkmk 10 Result: KORNJACA
desifriraj "vliuludqmh 3 Result: SIFRIRANJE
Rjeenje. Rjeenje je slino rjeenju prethodnog zadatka. Umjesto zbrajanja oduzimamo i pazimo da dobiveni broj bude izmeu 0 i 25 jer e brojevi moda biti manji od nule.
Meutim, moe se uoiti da je ifriranje kada je parametar :n jednak 26 (odnosno i svi viekratnici broja 26) jednako kao da nismo ni ifrirali. A moemo uoiti i to da je jednako ako dva puta ifriramo brojem 1 kao i da jedanput ifriramo brojem 2. Na taj nain jednako je ifriramo li brojem :n, a zatim ponovo brojem 26 :n kao i da smo odmah ifrirali brojem 26 26+ =:n :n . to znai da bi deifriranje brojem :n bilo isto to i ifriranje brojem 26 :n . Trebamo samo jo obratiti panju da taj broj ne bude manji od nule.
to desifriraj :t :n op sifriraj :t 26-remainder :n 26 end
Zadatak 60. Napiite funkciju sifriraj :t :k koja vraa ifrirani tekst :t uz pomo kljua :k. Parametri :t i :k rijei su koje se sastoje samo od slova AZ (njih ukupno 26). Svakom od tih 26 slova pridruimo broj od 0 do 25 ( A 0= , B 1= , ..., Z 25= ). ifrirani tekst takoer se sastoji od slova AZ. Slovo ifriranog teksta dobijemo tako da zbrojimo vrijednosti slova na toj istoj poziciji iz :t i iz :k. Ako je dobiveni broj vei od 25, umanjimo ga za 26.
Primjeri ifriranja:
-
256 LOGO za napredne
:T = ABCD = 0 1 2 3 :K = EFGH = 4 5 6 7 Rezultat = EGIK = 4 6 8 10
:T = VINKO = 21 8 13 10 14 :K = PAPIR = 15 0 15 8 17 Rezultat = KICSF = 10 8 2 18 5
Ako je duljina rijei :t vea od duljine rijei :k tada na rije :k dodajemo jo slova s poetka rijei :k.
Primjeri za provjeru:
sifriraj "abcd "efef Result: EGGI
sifriraj "vinko "logo Result: GWTYZ
sifriraj "kriptografija "papir Result: ZRXXKDGGIWXJP
Rjeenje.
to sifriraj :t :k make "rj " for "i 1 count :t [make "rj lput char 65+ remainder ((ascii item :i :t)-65+(ascii item (remainder (:i-1) count :k)+1 :k)-65) 26 :rj] op :rj end
Zadatak 61. Napiite funkciju desifriraj :t :k koja vraa deifrirani tekst :t uz pomo kljua :k (iz prethodnog zadatka).
Primjeri za provjeru:
desifriraj "eggi "efef Result: ABCD
desifriraj "gwtyz "logo Result: VINKO
desifriraj "zrxxkdggiwxjp "papir Result: KRIPTOGRAFIJA
-
6. Zadaci 257
Rjeenje.
to desifriraj :t :k make "rj " for "i 1 count :t [make "rj lput char 65+remainder ((ascii item :i :t)-65+26-(ascii item (remainder (:i-1) count :k)+1 :k)+65) 26 :rj] op :rj end
Ovu metodu mogli smo i zakomplicirati tako da rijei :k, u sluaju da je prekratka, dodajemo slova rijei :t ili slova onog to nastaje nakon ifriranja...
6.9 Razliiti zadaci
Zadatak 62. Napiite proceduru pravokut :a :b koja brie ekran i crta pravokutnik kojemu su stranice paralelne s rubovima ekrana, ali tako da su horizontalne stranice dulje.
Parametri :a i :b su brojevi.
Primjeri za provjeru:
pravokut 100 -200 pravokut -200 100 pravokut 150 -150
Rjeenje. Razlika u odnosu na vrlo slian zadatak iz 4. poglavlja je da u tekstu ne pie da su parametri :a i :b vei od nule. Ako na to ne pazimo, mogli bismo dobiti pogreke.
to pravokut :a :b cs if (abs :a)
-
258 LOGO za napredne
Zadatak (UP2002, I-4). Pripremljena je staza za posljednju utrku slaloma sezone. Iskusni trener je odredio pozicije vrata. Svaku poziciju je napisao na jedan papiri. Ivica je nabavio te papirie, ali mu se pomijeao redoslijed. Vi mu pomozite i napravite program koji e iscrtati stazu. Naravno, staza ne smije samu sebe presijecati (slika lijevo gore; vrata su
oznaena kruiima), i ne smije se dva puta proi kroz ista vrata (slika lijevo dolje). Slike desno su primjeri dobre staze.
Napiite proceduru staza :l koja crta stazu. Varijabla :l je lista koja se sastoji od nekoliko (bar jednih) vrata. Vrata su dvolana lista koja odreuje poziciju vrata na ekranu. (Gornji primjeri na slikama su staza [[0 0] [50 -50] [50 -25] [10 -80]], a donji staza [[0 0] [5 -50] [60 -50] [25 -50] [10 -75]].)
Primjeri za provjeru:
cs staza [[0 0] [200 200]] cs staza [[0 0] [200 200] [0 200] [200 0]] cs staza [[200 0] [0 200] [200 200] [0 0]] cs staza [[0 0] [100 100] [50 30] [10 40] [20 70]
[70 60]]
Rjeenje. Uoimo da stazu neemo presijecati ako su toke poredane po veliini (sortirane) po y-koordinati. Tj, ako prvo prolazimo kroz gornja vrata pa ona iza njih i tako sve do kraja (kao u gornjem primjeru). Meutim, mogua je situacija da vie toaka ima istu y-koordinatu. U tom sluaju te toke moramo poredati i po x-koordinati (da ne bi bili u situaciji donjeg primjera izgleda kao dvostruki
Slika 46
(0, )0
(50, )25
(50, )50
(10, )80(0,0)
( , 50)5 (10, 75)
( , 50)25 ( , 50)60
Slike 45
-
6. Zadaci 259
prolazak kroz ista vrata). Tj, kreemo od lijevih vrata nadesno sve dok ne proemo sva vrata na toj visini.
to manji :l1 :l2 if (last :l1) > (last :l2) then op :l1 if and((last:l1)=last:l2)((first:l1)
-
260 LOGO za napredne
Rjeenje.
to palindrom :w for "i 1 int / count :w 2 [if not (item :i :w)=item count :w :i-1 :w op "false] op "true end
Zadatak 64. Napiite funkciju zbroj :n :l koja ispisuje zbroj prvih :n elemenata liste :l.
Ako lista :l ima manje od :n elemenata, tada na kraj liste dodajemo listu, ali u obrnutom redoslijedu i s promijenjenim predznakom elemenata. Ako lista jo uvijek ima manje od :n elemenata, ponavljamo postupak s novonastalom listom i tako sve dok ne dobijemo listu sa :n ili vie elemenata.
Parametar :n je prirodan broj, dok je :l lista koja se sastoji od brojeva (barem jednog).
Primjeri za provjeru:
zbroj 3 [1 2 3] Result: 6 Jer je 1 2 3 6+ + = .
zbroj 3 [1 2 3 4] Result: 6 Jer je 1 2 3 6+ + = .
zbroj 5 [1 2 3] Result: 1 Jer je 1 2 3 3 2 1+ + = .
zbroj 10 [1 2 5 6] Result: 3 Jer je 1 2 5 6 6 5 2 1 1 2 3+ + + + + = .
Rjeenje.
to zbroj :n :l make "z 0 make "n remainder :n 2*count :l if :n>count :l make "n (2*count :l)-:n
if :n>0 [for "i 1 :n [make "z :z + item :i :l]] op :z end
-
6. Zadaci 261
Zadatak 65. Napiite proceduru boje :d :n koja crta :n rombova od kojih svaka 2 susjedna imaju jednu zajedniku stranicu. Svi rombovi imaju zajedniki jedan vrh (u sreditu slike 47). Rombovi su ravnomjerno rasporeeni (kao na slici 47 kut ), tako da zatvaraju puni kut.
Zajednike stranice rombova neka budu bijele boje (broj 15) (na slici 47, zbog bijelog papira, crna boja). Ostale 2 stranice svakog romba neka budu jedne od boja: crvena (12), uta (14) ili plava (9), ali tako da su susjedni rombovi razliiti po boji (kao na slici 47).
Na slici 47 je primjer za 10=:n . Jedan je romb osjenan zbog lakeg uoavanja.
Parametar :d je broj vei od nule, dok je parametar :n prirodan broj vei od 2.
Primjeri za provjeru:
cs boje 200 3 cs boje 150 4
cs boje 100 5 cs boje 100 6
cs boje 70 15 cs boje 70 17
Rjeenje.
to izaberi_boju :i if :i=0 op 15 if :i=1 op 9 if (remainder :i 2)=1 op 12 op 14 end
to romb :d :n :i setpc izaberi_boju 0 make "g_a 360/:n fd :d
setpc izaberi_boju:i lt :g_a fd :d lt 180-:g_a fd:d
d
d
Slika 47
-
262 LOGO za napredne
setpc izaberi_boju 0 lt :g_a fd :d lt 180-:g_a end
to boje :d :n for "i 1 :n[romb :d :n :i rt 360/:n] end
Zadatak 66. Napiite proceduru zid :w :h :n :s koja brie ekran i crta zid koji ima :n cigala. Svaka je cigla pravokutnik irine :w i visine :h. Zid je irok :s toaka.
Zid crtamo od donjeg lijevog ruba. Slaemo ciglu do cigle nadesno. Kada zid bude irok :s, zapoinjemo novi red cigala iznad ve nacrtanog, ali s desna na lijevo. Kada doemo do kraja reda, novi red zapoinjemo ponovo slijeva nadesno itd. (Na slici 48 brojevi na ciglama oznaavaju redoslijed kojim je zid sazidan.)
Slika 48
Ako neka cigla (na kraju reda) prelazi zadanu irinu reda, presjeemo ju na potrebnu irinu i novi red zapoinjemo sa odsjeenim komadom cigle. (Kao na slici 48 iscrtkane cigle broj 3 i 6 odsjeeni komadi su osjenani.)
Na slici 48 vidimo primjer zida koji se sastoji od 8 cigala irine 100.
Parametar :n je prirodan broj. Parametri :w :h i :s su brojevi vei od nule. Obratite panju da je mogue i da je varijabla :w i vie nego dvostruko vea od varijable :s.
Primjeri za provjeru:
-
6. Zadaci 263
zid 100 35 15 310 zid 100 35 8 270
zid 100 35 2 270 zid 100 35 15 300
zid 30 20 30 160 zid 300 25 2 70
zid 100 35 8 200 zid 100 20 3 3
Rjeenje.
to cigla :w fd :h rt 90 fd :w rt 90 fd :h rt 90 fd :w bk :w rt 90 end
to novi_red make "parnost_reda not :parnost_reda if :parnost_reda then [fd 2*:h] rt 180 end
to zid :w :h :n :s cs make "parnost_reda "false make "ps :s repeat :n [make "k :w while [:k>:ps] [cigla :ps make "k :k - :ps novi_red make "ps :s] cigla :k make "ps :ps-:k] end
Zadatak 67. Ivica je odluio sagraditi zid. Tata mu je zadao irinu zida i broj redova (na slici 49 imamo 3 reda). Pero ima vie vrsta cigala sve u obliku pravokutnika (na slici imamo 4 cigle irine 100, i bar 7 cigala irine 60). Sreom, visina svih cigli je jednaka (na slici je visina 35).
Ivica poinje zidati zid od donjeg lijevog ruba, slae ciglu do cigle nadesno (kako pokazuju brojevi na ciglama) i to uzimajui prvo najvee cigle. Kada sazida potrebnu irinu (na slici je irina zida 270), zapoinje novi red iznad upravo sazidanog, ali s desna na lijevo. Sljedei red zida ponovo slijeva nadesno itd.
-
264 LOGO za napredne
Slika 49
Ako je zadnja cigla u redu prevelika (na slici iscrtkane cigle broj 3 i 7), Ivica ju presjee i sljedei red nastavlja zidati s tim odsjeenim komadom cigle (osjenani dio). Kada potroi sve cigle odreene veliine, nastavlja zidati s najveim ciglama od preostalih. Kada zavri sa zidanjem, preostale cigle spremi na hrpu za idui zid. (Na slici je, ako je bilo 7 cigala irine 60, ostala jedna cigla irine 10 odsjeeni komad jedanaeste cigle zatamnjeni dio u gornjem desnom uglu slike).
Napiite funkciju zid :w :n :l :h koja brie ekran i crta zid irine :w i vraa listu cigli koje su jo preostale. Ako je cigala bilo tono za zid, funkcija vraa praznu listu. Ako je cigala bilo premalo, funkcija vraa broj 0.
Parametar :w je pozitivan broj. Parametar :n je prirodan broj koji oznaava broj redova cigala. Lista :l se sastoji od bar jedne dvolane liste. Prvi element dvolane liste je pozitivan broj koji oznaava irinu cigle, a drugi je prirodan broj koji oznaava koliko takvih cigala imamo. Svake dvije dvolane liste imaju razliite prve brojeve (cigle su grupirane po irini). Parametar :h je pozitivan broj koji oznaava visinu cigle. Obratite panju da je mogu sluaj kad je irina neke cigle i vie nego dvostruko vea od irine zida.
U gore opisanom primjeru (ZID 270 3 [[100 4] [60 7]] 35), funkcija treba vratiti listu [[10 1]].
Preostale cigle grupirajte tako da su podaci o ciglama jednake veliine zapisani u jednoj dvolanoj listi (ukljuujui i eventualno preostali odsjeeni komad cigle drugi primjer ispod). Redoslijed grupa cigala nije bitan (u prvom je primjeru prvo jedna manja cigla, pa dvije vee, dok su u drugom prvo dvije vee, pa etiri manje).
Primjeri za provjeru:
-
6. Zadaci 265
zid 270 3 [[100 4][60 9]] 35Result: [[10 1] [60 2]]
zid 270 3 [[100 4][60 9][10 3]] 35 [60 2] [10 4]
zid 270 5 [[100 7][60 10][25 2]] 35 Result: []
zid 270 3 [[100 4][60 5]] 350
Rjeenje.
to najveci :l make "j 1 for "i 2 count :l [if (first item :j :l)
-
266 LOGO za napredne
to nova_cigla if empty? :cigle then [op "false] make "komad first first :cigle if (count :cigle)>1 make "o bf :cigle else make "o [] make "c (last first :cigle)-1 if :c>0 make "cigle fput list :komad :c :o else make "cigle :o op "true end
to crtaj_red :parnost if :parnost=0 then [fd 2*:h] rt 180 make "ostalo :w while [and (:komad0)] [ if :komad>0 then [cigla :komad make "ostalo :ostalo-:komad make "komad 0] else [if not nova_cigla then [op "false]]] if :ostalo>0 then [make "komad :komad-:ostalo cigla :ostalo] op "true end
to sredijednu make "k item :i :cigle if and (:komad=first :k) (not :bio) then [make "bio "true make "k list first :k (1+last :k)] make "l fput :k :l end
to sredigrupe if :komad
-
6. Zadaci 267
while [:broj_reda
-
268 LOGO za napredne
op :l end
to crt_kv :l1 :l2 :l3 :l4 pu setxy :l1 pd setxy :l2 setxy :l3 setxy :l4 setxy :l1 end
to kvadrati :n :d pd if (:n=0) [repeat 4[fd :d rt 90] stop] make "kord1 linija :n :d rt 90 make "kord2 linija :n :d rt 90 make "kord3 linija :n :d rt 90 make "kord4 linija :n :d rt 90 for "j 1 :n [crt_kv item :j :kord1 item :j :kord2 item :j :kord3 item :j :kord4] end
Napomena 7. Ovaj zadatak mogli smo rijeiti i pomou formula za dijeljenje duine u omjeru (iz drugog poglavlja). itatelju preputam da sam pokua sastaviti rjeenje.