#include "cpp_headers/fcpp.hh"

// prueft ob Zahl gerade oder nicht
int iseven(int n) {
    return n % 2 == 0;
}

// berechnet Quadrat einer Zahl
int square(int x) {
    return x * x;
}

// berechnet x^exp schnell
int potenz(int x, int exp) {
    return cond(exp == 1, // falls exp == 1
                x, // x^1 = x
                cond(iseven(exp),
                     square(potenz(x, exp / 2)), // wenn gerade
                     x * potenz(x, exp-1))); // wenn ungerade
}

// summiert alle echten Teiler einer zahl auf
int summiereTeiler(int summe, int index, int zahl) {
    // der index stellt den aktuellen zu pruefenden Teiler dar
    // falls dieser groeßer ist als die Haelfte der Zahl, kann es keine
    // echten Teiler mehr geben, d.h. es wird die aktuelle Summe zurueckgegeben
    return cond(index > zahl / 2,
                summe,
                // falls index die zahl teilt, wird die Summe um index erhöht
                // danach wird der nächste moegliche Teiler geprueft
                summiereTeiler(cond(zahl % index == 0, summe + index, summe),
                               index + 1,
                               zahl));
}

// berechnet ob eine Zahl vollkommen ist
bool vollkommen(int zahl) {
    // summiere alle Teiler und pruefe ob die Zahl gleich dieses Summe
    // es wird mit der Startsumme 0 und dem ersten Teiler 1 gestartet
    return summiereTeiler(0, 1, zahl) == zahl;
}

int main() {
    return print(potenz(2, 10),
                 cond(vollkommen(8128),
                      "8128 ist vollkommen",
                      "8128 ist nicht vollkommen"),
                 0);
}
