{

`Oplossingen oefeningenreeks 3`
`*****************************`

`Oefening 1`

sign(x) : if(x>0, 1, if(x<0, -1, 0));


`Oefening 2`

divides(x,d) : (x \\ d) = 0;

`Oefening 3`

leap_year(year) : if(divides(year, 400), 
                     true,
                     if(divides(year, 100),
                        false,
                        if(divides(year, 4),
                           true,
                           false)));

leap_year(year) : if(divides(year,4),
                     if(divides(year,100),
                        divides(year,400),
                        true),
                     false);

`Oefening 4`

count1(x) : if(x=0, display(x), {display(x); count1(x-1)});

count2(x) : if(x=0, display(x), {count2(x-1); display(x)});

`43210`
`01234`
count1(4);
display(eoln);
count2(4);
display(eoln);

`Oefening 5`

dec(x) : x - 1;
inc(x) : x + 1;

plus(x,y) : if(y=0, x, inc(plus(x,dec(y))));
min(x,y) : if(y=0, x, dec(min(x,dec(y))));

`Oefening 6`

even(x) : void;

odd(x) : if(x=0, false, even(x-1));
even(x) := if(x=0, true, odd(x-1));              
                     

`Oefening 7`

ackermann(x,y) : if(x=0,
                    y+1,
                    if(y=0,
                       ackermann(x-1,1),
                       ackermann(x-1, ackermann(x,y-1))));

`Opgepast: deze functie stopt niet meteen als je ze oproept met iets anders dan kleine waarden!`

`Oefening 8`

gcd(a,b) : if(b=0, a, gcd(b, a \\ b));

`Oefening 9`

`b^n = b^(n/2)^2 if n even`
`b^n = b.b^(n-1) if n odd`

square(x) : x * x; 

fastpower(x,n) : if(n=0,
                    1,
                    if(even(n), 
                       square(fastpower(x,n/2)),
                       x * fastpower(x, n-1)));

`Extraatje (niet te kennen):`
`Het berekenen van b^(2n) neemt nu slechts een vermenigvuldiging meer in beslag dan het berekenen van b^n. De grootte van de exponent die we kunnen berekenen verdubbelt met elke vermeningvuldiging die we mogen maken. Het aantal vermenigvuldigingen dat we moeten maken voor een machtsverheffing met exponent n groeit dus zo snel als het logaritme van n met basis 2, terwijl dit vroeger gewoon meegroeide met n. Voor grote getallen maakt dit een heel verschil.`

`Oefening 10`

displaybinary(n) : if(n=0,
                      display("0"),
                      {displaybinary(n//2);
                       if(even(n),
                          display("0"),
                          display("1"))});

displaybinary(9);

displaybinary2(x) : if(x=0, display(0), {displaybinary2(x//2); display(x\\2)});

binair(n) : if(n=0,display(0), { binair(n//2) ; display(n\\2)});
mod1(n,m) : if(n=0,display(0), { mod1(n//m,m) ; display(n\\m," ")});
mod(n) : f(x) : mod1(x,n);

display("2568 in binair: ",binair(2568),eoln,eoln);
display("m3 : mod(3)",eoln,m3:mod(3),eoln);
display("2568 in het drie tallig talstelsel: ",m3(2568),eoln,eoln);
display("m16 : mod(16)",eoln,m16:mod(16),eoln);
display("2568 in het 16 tallig talstelsel: ",m16(2568),eoln,eoln);
         

`Oefening 11`

`ahv recursie`
toonTafel(n) : { 
  multiply(x) : 
   if(x=11,
      display(eoln),
      {display(n, " x ", x, " = ", n * x, eoln);
       multiply(x+1)});

  multiply(0) 
}

toonTafel(7);

`ahv while`
toonTafel(n) : { x : 0;
                 while(x<11,
                       {display(n, " x ", x, " = ", n * x, eoln);
                        x := x+1})
               };
toonTafel(9);

`ahv for`
toonTafel(n) : for (i:0 , i<=10, i:=i+1, display( i, " x " , n , " = " , i*n ,eoln ));
		
`Oefening 12`

delers(n) : for(i:1,
                i<=n,
		i:=i+1,
                if((n\\i)=0,display(i), display(" ")));

`Oefening 13`

smallest_divisor(n) :if(n=1,
                        1,
                       {i : 1; until(n\\i=0, i:=i+1)});

`dit kan sneller: je moet namelijk niet helemaal tot n lopen om te besluiten dat het getal geen van 1 verschillende delers heeft ...`
                
printprimes() : 
   for(i:2,
       i<101,
       i:=i+1,  
       if(smallest_divisor(i)=i, display(i, " "), void));


`Oefening 14`

sum_integers(a,b) :
 if(a>b,
    0,
    a + sum_integers(a+1,b));

sum_integers(a,b) : {
   result : 0;
   for(i:a, i<b+1, i:=i+1, result:=result+i)} ;


`Oefening 15`

`Bij het uitwerken van een reeks zal je soms zien dat ik voor een variabele`
`die de waarde 0 moet hebben, expliciet 0.0 schrijf ipv 0.`
`Dit is omdat kommagetallen in Pico grotere waarden kunnen bevatten.`
`Als er in onderstaande definitie 1 ipv 1.0 gestaan had, was het niet mogelijk`
`om een faculteit groter dan die van 12 te berekenen (probeer maar eens) zonder`
`dat de functie * begint te klagen dat het resultaat te groot geworden is om`
`in 30 bits (teken inclusief) te passen.`

fac(x) : if(x=0,1.0,x*fac(x-1));

calc_sin(x,n) : 
  { result:0.0;
    sign:1;
    frac:1;
    term:1;
    while(term<n+1, 
          { result := result + sign * (x^frac) / fac(frac);
            sign := -sign;
            frac := frac+2;
            term := term+1});
    result 
  };

calc_cos(x,n) : {
   result:0.0;
   sign:1;
   frac:0;
   term:1;
   while(term<n+1,
         {result := result + sign * (x^frac) / fac(frac);
          sign := -sign;
          frac := frac+2;
          term := term+1});
    result
 };

sinus(x,n) : for({a:0;i:0},i<n,i:=i+1, a := (a + sign((-1)^i) * x^(2*i+1) / fac((2*i+1))) );
cosinus(x,n) : for({a:0;i:0},i<n,i:=i+1, a := (a + sign((-1)^i) * x^(2*i) / fac((2*i))) );
tangens(x,n) : sinus(x,n)/cosinus(x,n);

`Oefening 17`

return_multiplier(n) : f(x) : x * n;

triple : return_multiplier(3); 
triple(2);
double : return_multiplier(2);
double(4);

`Oefening 18`

compose(f,g) : composed(x) : f(g(x));
timessix : compose(double, triple);
timessix(6);

`Oefening 19`

square(x) : x * x;
sum_squares(a,b) : if(a>b, 0, square(a) + sum_squares(a+1,b));

`Oefening 20`

sum_every_two_integers(a,b) : if(a>b, 0, a + sum_every_two_integers(a+2,b));

`Oefening 21`

pisum(a,b) : if(a>b, 0, 1 / (a * (a+2)) + pisum(a+4,b));

`Oefening 23`

sum(term, next, a, b) : if(a>b, 
                           0,
                           term(a) + sum(term, next, next(a), b));

id(x) : x;
inc(x) : x+1;
sum_integers(a,b) : sum(id, inc, a, b);

square(x) : x*x;
sum_squares(a,b) : sum(square, inc, a, b);

plustwo(x) : x+2;
sum_every_two_integers(a,b) : sum(id, plustwo, a, b);

piterm(x) : 1 / (x * (x+2));
plusfour(x) : x+4;
pisum(a,b) : sum(piterm, plusfour, a, b);
pisum(1,1000)*8;


`Oefening 24`

fixpunt(epsilon,gok,f):
    { nieuw: f(gok);
      delta: abs(gok-nieuw);
      if(delta<epsilon,
        nieuw,
        fixpunt(epsilon,nieuw,f))};

fixpunt(0.0000001, 1, cos);

`Oefening 25`

fixpunt1(epsilon,gok,f):
    { nieuw: f(gok);
      delta: abs(gok-nieuw);
      display("gok: ", gok, " | nieuwe gok: ", nieuw, eoln);
      if(delta<epsilon,
        nieuw,
        fixpunt1(epsilon,nieuw,f))};

 
`Oefening 26`

`sqrt(number)=x`
`<=> number = x^2`
`<=> number/x = x`
`dit is waar voor de fixpunten van de functie f(x) = number/x`

vierkantswortel(getal) : {
	f(x) : getal / x;
	fixpunt1(0.01, 1, f)
};


`sqrt(100) en sqrt(4) werken niet zonder demping!`

`Oefening 27`


fixpunt2(epsilon,gok,f):
    { nieuw: (gok + f(gok)) / 2;
      delta: abs(gok-nieuw);
      display("gok: ", gok, " | nieuwe gok: ", nieuw, eoln);
      if(delta<epsilon,
        nieuw,
        fixpunt2(epsilon,nieuw,f))};

vierkantswortel(getal) := {
	f(x) : getal / x;
	fixpunt2(0.01, 1, f)
};

vierkantswortel(4);


`Oefening 29`

compose(f(x),g(y)) : composed(z) : f(g(z));
timessix : compose(x*2, y*3);
timessix(6);


`Oefening 30`

average_damp(f(z)) : averaged(x) : (x + f(x)) / 2;
dx : 0.00001;
derivative(f(z)) : derived(x) : (f(x + dx) - f(x)) / dx;
d : derivative(z^3 + z^2 + z + 10);
d(5)

   
}