Przykładowe (być może nie
jedyne wcale!) właściwe rozwiązania zadań z omówieniami
Zad. A. Program wypisujący na ekranie reszty z dzielenia
przez 7 kolejnych naturalnych potęg czwórki nieprzekraczających miliona.
Var potega:LongInt; {Moze byc tez Real, ale wtedy jest klopot z
wyswietlaniem, no i po co, skoro
te wartosci sa
calkowite, a patrz uwaga wyżej!}
Begin
potega:=1; {Można tez zaczac od 4,
jeśli uznac, ze naturalne potegi to te,
które maja wykladniki calkowite dodatnie.}
While potega<=1000000 do {Może
być tez ostra nierownosc, bo akurat tu wiemy, ze dokladnie 1000000 nigdy nie
będzie.}
Begin
potega:=potega*4;
{*} WriteLn(potega mod 7);
{srednik zbedny}
End; {srednik zbedny}
End.
Tak napisany program NIE JEST poprawny z tego samego
powodu, co nasze pierwsze podejście do wypisywania liczb pierwszych na
ostatnich zajęciach! - Wypisze również resztę z dz. p. 7 najmniejszej potęgi
przekraczającej milion! (Poza tym nie drukuje tej reszty dla początkowej
wartości potęgi). Linię {*} można więc opatrzyć warunkiem (i ew. dodatkowo
rozpatrzyć wartość początkową przed pętlą) albo po prostu przenieść przed
zwiększanie potęgi! J
Zad. B.
W Pascalu zapisujemy definicję:
Function g(a:Real; b:LongInt):xxx;
Begin
If b=0 then
g:=0
else
g:=a+g(a,b-1)
End;
a) Co powinniśmy wpisać w miejsce „xxx”? Dlaczego?
„Real”, bo wartość g może (przy b>0) być
sumą, której jeden ze składników (a) jest typu Real. Uzasadnienie
„bo a jest typu Real” jest niewystarczające! Stała pi też jest
typu Real, i co z tego?! Co więcej – łatwo wyobrazić sobie funkcję o argumencie
typu Real, a wartościach całkowitych (jak choćby signum czy entier)!
b) Pokaż, jak Pascal obliczy g(11,3). Ile wynosi
ta wartość?
g(11,3) = 11+g(11,2)
= 11+(11+g(11,1)) = 11+(11+(11+g(11,0))) = 11+(11+(11+0)) = 33
Zad. C. Program znajdujący sumę wszystkich podzielnych
przez 3 liczb czterocyfrowych, których przedostatnia cyfra jest nieparzysta.
Var c1,c2,c3,c4,suma:LongInt; {Kolejne cyfry kolejnych liczb 4-cyfrowych i szukana suma.}
Begin
suma:=0;
For c1:=1 to 9 do
For c2:=0 to 9 do
For
c3:=0 to 9 do {Tu mozna podarowac sobie
0 - dlaczego?)
For c4:=0 to 9 do
If c3 mod 2 =1 then
If (c1+c2+c3+c4) mod 3 =0 {Nawias konieczny! - dlaczego?} then
suma:=suma+((c1*10+c2)*10+c3)*10+c4; {Przyklad
zastosowania schematu Hornera
- oczywiscie mozna tez "normalnie".}
WriteLn(suma); {srednik zbedny}
End.
Powyższy program niepotrzebnie wchodzi w najbardziej
wewn. pętlę, gdy przedost cyfra jest parzysta – nietrudno można go ulepszyć –
jak?
Można też dla danego układu (c1,c2,c3,c4)
wygenerować sobie odpowiednią 4-cyfrową liczbę (1000c1+100c2+10c3+c4)
i bezpośrednio sprawdzać jej podzielność przez 3 oraz ew. dodać. Wówczas jednak
potrzebne będą begin i end - czemu?
A można też całkiem zupełnie diametralnie (?) inaczej
(ciekawe, czy wyjdzie to samo...):
Var
liczba,suma:LongInt;
Begin
suma:=0;
For liczba:=1000 to 9999 do {Zaczac petle mozna (ale czy warto?)
nawet od 1011 – dlaczego?}
If liczba mod 3 =0
then
If
(liczba div 10) mod 2 =1 {O co tu chodzi??
A nawias dla pewnosci – nie wiem, czy jest
potrzebny, ale sadze, ze absolutnie nie warto tego sprawdzac!} then
suma:=suma+liczba;
WriteLn(suma); {srednik zbedny}
End.
Zad. D. Pascalowa rekurencyjna definicja ciągu
arytmetycznego o pierwszym wyrazie 7 i różnicy -2.
Ciąg jest formalnie definiowany jako funkcja (o
dziedzinie...?). Rekurencja polega na odwołaniu się funkcji (czy też procedury)
do samej siebie. Ciąg arytmetyczny powstaje przez dodawanie do kolejnych
wyrazów pewnej stałej (różnicy). Będzie więc np. po prostu:
Function
ca(n:LongInt):LongInt; {Typem wyniku moze byc Real, ale po co?!}
Begin
If
n=1 then ca:=7 {Niektore podreczniki wola numerowac wyrazy od 0, ale my
umawialismy sie zaczynac od 1.}
else ca:=ca(n-1)-2
End;
Życzę miłej nauki i wysokich wyników na egzaminie!
M.Ś.