// Solutions to "Richard Kaiser: C++ with Borland C++Builder", ISBN: 3540010270
// Copyright Richard Kaiser, 2004, All rights reserved
// oder doch besser weglassen ???

// --------------- Aufgaben 3.10.1 -------------------------

// --------------- Aufgabe 1. ------------------------------

void ArrayTest1()
{
int a[10];
for (int i=1; i<=10;i++) a[i] = 0;   // a)

int b[2], c[2], d[3];
b[0]=0; b[1]=1;
//c=b;                               // b)

int x=b[b[b[0]]];                    // c)
c[0]=0; c[1]=1;
d[0]=0; d[1]=1; d[2]=2;
if (b==c) x++;                       // d)
if (c==d) x++;                       // e)

int s1=sizeof(a);                    // f)
int s2=sizeof(a)/sizeof(a[0]);       // g)
// a) Fehler: Zugriff auf a[10]
// b) Zuweisung von Arrays ist nicht möglich
// c) x=0
// d) b==c vergleicht die Adressen und nicht die Arrays
// e) wie b); da die Arrays verschieden groß sind,
//    kann das kein Vergleich der Arrayelemente sein
// f) s1=2*sizeof(int)=8
// g) s2=8/4=2, Anzahl der Arrayelemente
}


// --------------- Aufgabe 2 -------------------------------

void SiebEratosthenes()
{
const int n=1000;
bool prim[n+1];
// p[i]==true, falls i eine Primzahl ist, sonst false
for (int i=0;i<n;i++) prim[i] = true;
for (int i=2; i<=n; i++)
  if (prim[i])
    for (int j=i;  j<=n/i; j++)
      prim[j*i] = false;
for (int i=2; i<=n; i++)
  if (prim[i])
    Form1->Memo1->Lines->Add(IntToStr(i));
};


// --------------- Aufgabe 3 -------------------------------

double MisesSimulation(int AnzahlPersonen)
{
int g[365];
int AnzahlVersuche=1000,
    AnzahlTreffer=0;
for (int i=1; i<=AnzahlVersuche; i++)
  {
    for (int j=0; j<365; j++) g[j] = 0;
    for (int j=1; j<=AnzahlPersonen; j++)
       g[rand()%365+1]++;
    bool gefunden = false;
    for (int j=0; j<365; j++)
      if (g[j] > 1) gefunden = true;
    if (gefunden) AnzahlTreffer++;
  };
Form1->Memo1->Lines->Add("n="+IntToStr(AnzahlPersonen)+" w="
+FloatToStr(1.0*AnzahlTreffer/AnzahlVersuche));
return 1.0*AnzahlTreffer/AnzahlVersuche;
}

void TestMisesSimulation()
{
MisesSimulation(23);
MisesSimulation(23);
MisesSimulation(23);
MisesSimulation(23);
MisesSimulation(23);

MisesSimulation(10);
MisesSimulation(20);
MisesSimulation(30);

// Die Simulationsergebnisse mit 1000 Versuchen stimmen recht
// gut mit den exakten Werten (in Klammern) überein:
/*
  n=23 w=0,499  (p=0,5073)
  n=23 w=0,508
  n=23 w=0,5
  n=23 w=0,535
  n=23 w=0,512

  n=10 w=0,116   (p=0,1169)
  n=20 w=0,414   (p=0,4114)
  n=30 w=0,69    (p=0,7063)
*/
}

// --------------- Aufgabe 4 -------------------------------

double Horner(double x)
{ // p: Array mit den Koeffizienten des Polynoms
const int n=2; // Der Grad des Polynoms
double p[n+1]={17,0,3}; // Koeffizienten von 17+3*x^2
double s = 0;
for (int i=0; i<n+1; i++)
    s = s*x + p[n-i];
return s;
}

/*
a)

Induktionsanfang: Nach der ersten Zuweisung s=s*x+...
  in der Schleife gilt (i==1) und (s==p[n]).

Induktionsvoraussetzung:
  Nach der k-ten Zuweisung s=s*x+...
  in der Schleife (vor i++) gilt (i==k) und

    s==p[n]*x^k + p[n-1]*x^(k-1) +...+ p[n-k+1]*x+p[n-k]

  Beim nächsten Schleifendurchlauf erhält i den Wert (i==k+1)
  und s den Wert:

    s==p[n]*x^(k+1) + p[n-1]*x^k +...+ p[n-k+1]*x^2+p[n-k]*x+p[n-(k+1)]

  Das ist gerade die Induktionsbehauptung für k+1.

  Beim letzten Durchlauf hat i den Wert n:

    s==p[n]*x^n + p[n-1]*x^(n-1) +...+ p[n-n+1]*x+p[n-n]
*/

// b)
double Horner_sin(double x)
{ // p: Array mit den Koeffizienten des Polynoms
double k3=3*2*1;
double k5=5*4*k3;
double k7=7*6*k5;
const int n=7; // Der Grad des Polynoms
double p[n+1]={0, 1, 0, -1/k3, 0, +1/k5, 0, -1/k7};
double s = 0;
for (int i=0; i<n+1; i++)
    s = s*x + p[n-i];
return s;
}

#include <cmath>
void test_HornerSinus()
{
for (int i=1 ;i<=31 ;i++ )
  {
  double x=i/10.0;
  double s1=std::sin(x);
  double s2=Horner_sin(x);
  Form1->Memo1->Lines->Add("x="+FloatToStrF(x,ffGeneral,6,6)+" sin="+s1+
         " Horn-sin="+FloatToStrF(s2,ffGeneral,2,2)+" diff="+std::abs(s1-s2));
  // Offensichtlich die Ergebnisse der Taylor-Reihe 
  // für kleine Werte gut mit den Werten der sin-Funktion überein.
  }
}
