21 goede antwoorden op vraag 3A van het tentamen GESPRG van 23 januari 2013.

© Harry Broeders.

Deze pagina is bestemd voor studenten van de Haagse Hogeschool - Academie voor Technology, Innovation & Society Delft.

Inleiding.

Op sommige vragen is maar één goed antwoord mogelijk. Op een programmeervraag kun je vaak heel veel goede antwoorden geven. Als voorbeeld zal ik op deze pagina 21 goede antwoorden laten zien op (de relatief eenvoudige) vraag 3A van het tentamen GESPRG van 23 januari 2013. Het is best leerzaam of te kijken of je al deze antwoorden begrijpt.

Vraag 3A van het tentamen van 23 januari 2013.

De vraag luidt als volgt:

Antwoord 1.

Dit is waarschijnlijk het meest eenvoudige antwoord. Bij dit antwoord maken we gebruik van het feit dat de integer waarde 0 in C als false wordt gezien en elke andere integer waarde (zoals 1) als true wordt gezien. We maken ook gebruik van het feit dat de operator && 0 (false) of 1 (true) teruggeeft. De operator && geeft (meteen) false terug als een operand de waarde false heeft. Dus als de functieaanroep checkGetallen(vierkant) een 0 oplevert dan worden de overige functies niet meer aangeroepen maar wordt meteen een 0 geretourneerd.

int isMagisch(int vierkant[8][8]) {
    return checkGetallen(vierkant) && checkSomRijen(vierkant) && checkSomKolommen(vierkant) && checkSomDiagonalen(vierkant);
}

Antwoord 2.

Bij dit antwoord worden de returnwaarden van de functieaanroepen expliciet vergeleken met de waarde 1.

int isMagisch(int vierkant[8][8]) {
    return checkGetallen(vierkant) == 1 && checkSomRijen(vierkant) == 1 && checkSomKolommen(vierkant) == 1 && checkSomDiagonalen(vierkant) == 1;
}

Antwoord 3.

Bij dit antwoord wordt de waarde 1 of 0 expliciet geretourneerd.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 1 && checkSomRijen(vierkant) == 1 && checkSomKolommen(vierkant) == 1 && checkSomDiagonalen(vierkant) == 1) {
        return 1;
    }
    return 0;
}

Antwoord 4.

Dit antwoord is bijna hetzelfde als antwoord 3. Er wordt in dit antwoord gebruik gemaakt van een if ... else in plaats van een if. Omdat de code in de if een return statement bevat maakt dat in dit geval niet uit.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 1 && checkSomRijen(vierkant) == 1 && checkSomKolommen(vierkant) == 1 && checkSomDiagonalen(vierkant) == 1) {
        return 1;
    }
    else {
        return 0;
    }
}

Antwoord 5.

Bij dit antwoord wordt het gedrag van && operator helemaal uitgeschreven met if instructies.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 1) {
        if (checkSomRijen(vierkant) == 1) {
            if (checkSomKolommen(vierkant) == 1) {
                if (checkSomDiagonalen(vierkant) == 1) {
                    return 1;
                }
            }
        }
    }
    return 0;
}

Antwoord 6.

Bij dit antwoord wordt het gedrag van && operator helemaal uitgeschreven met if ... else instructies.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 1) {
        if (checkSomRijen(vierkant) == 1) {
            if (checkSomKolommen(vierkant) == 1) {
                if (checkSomDiagonalen(vierkant) == 1) {
                    return 1;
                }
                else {
                    return 0;
                }
            }
            else {
                return 0;
            }
        }
        else {
            return 0;
        }
    }
    else {
        return 0;
    }
}

Antwoord 7.

Bij dit antwoord wordt het gedrag van && operator helemaal uitgeschreven met if instructies op een andere manier dan bij antwoord 5.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 0) {
        return 0;
    }
    if (checkSomRijen(vierkant) == 0) {
        return 0;
    }
    if (checkSomKolommen(vierkant) == 0) {
        return 0;
    }
    if (checkSomDiagonalen(vierkant) == 0) {
        return 0;
    }
    return 1;
}

Antwoord 8.

Dit antwoord is gevonden door de wetten van De Morgan toe te passen op antwoord 3.

int isMagisch(int vierkant[8][8]) {
    if (checkGetallen(vierkant) == 0 || checkSomRijen(vierkant) == 0 || checkSomKolommen(vierkant) == 0 || checkSomDiagonalen(vierkant) == 0) {
        return 0;
    }
    return 1;
}

Antwoord 9.

Bij dit antwoord wordt geteld hoeveel functieaanroepen de waarde 1 teruggeven. Als dat er 4 zijn dan is het vierkant magisch.

int isMagisch(int vierkant[8][8]) {
    int aantalEnen = 0;
    if (checkGetallen(vierkant) == 1) {
        aantalEnen++;
    }
    if (checkSomRijen(vierkant) == 1) {
        aantalEnen++;
    }
    if (checkSomKolommen(vierkant) == 1) {
        aantalEnen++;
    }
    if (checkSomDiagonalen(vierkant) == 1) {
        aantalEnen++;
    }
    if (aantalEnen == 4) {
        return 1;
    }
    else {
        return 0;
    }
}

Antwoord 10.

Bij dit antwoord worden de returnwaarden van de functieaanroepen bij elkaar opgeteld. Als deze som 4 is dan is het vierkant magisch. Het grote verschil met de antwoorden die gebruik maken van de operator && (zie bijvoorbeeld antwoord 1) is dat bij het gebuik van de operator + alle vier de functies altijd zullen worden aangeroepen. Dit antwoord is dus minder efficient dan antwoord 1.

int isMagisch(int vierkant[8][8]) {
    int som = checkGetallen(vierkant) + checkSomRijen(vierkant) + checkSomKolommen(vierkant) + checkSomDiagonalen(vierkant);
    return som == 4;
}

Antwoord 11.

Dit antwoord combineert de twee instructies uit antwoord 10 tot één instructie. De lokale variabele som is dan niet meer nodig.

int isMagisch(int vierkant[8][8]) {
    return checkGetallen(vierkant) + checkSomRijen(vierkant) + checkSomKolommen(vierkant) + checkSomDiagonalen(vierkant) == 4;
}

Antwoord 12.

Bij dit antwoord wordt een lokale variabele op 1 geïnitialiseerd en op 0 gezet als een functieaanroep niet de waarde true teruggeeft. Dit antwoord lijkt een beetje op antwoord 7. Het grote verschil met antwoord 7 is dat in dit geval alle vier de functies altijd zullen worden aangeroepen. Dit antwoord is dus minder efficient dan antwoord 7.

int isMagisch(int vierkant[8][8]) {
    int ok = 1;
    if (!checkGetallen(vierkant)) {
        ok = 0;
    }
    if (!checkSomRijen(vierkant)) {
        ok = 0;
    }
    if (!checkSomKolommen(vierkant)) {
        ok = 0;
    }
    if (!checkSomDiagonalen(vierkant)) {
        ok = 0;
    }
    return ok;
}

Antwoord 13.

Dit antwoord lijkt erg veel op antwoord 12. Er is driemaal een else toegevoegd. Bij dit antwoord wordt een lokale variabele op 1 geïnitialiseerd en op 0 gezet als een functieaanroep niet de waarde true teruggeeft. De volgende if wordt alleen uitgevoerd als de vorige functieaanroep de waarde true teruggeeft. Het grote verschil met antwoord 12 is dus dat in dit geval niet alle vier de functies altijd zullen worden aangeroepen. Dit antwoord komt wat dat betreft overeen met antwoord 7.

int isMagisch(int vierkant[8][8]) {
    int ok = 1;
    if (!checkGetallen(vierkant)) {
        ok = 0;
    }
    else if (!checkSomRijen(vierkant)) {
        ok = 0;
    }
    else if (!checkSomKolommen(vierkant)) {
        ok = 0;
    }
    else if (!checkSomDiagonalen(vierkant)) {
        ok = 0;
    }
    return ok;
}

Antwoord 14.

Dit antwoord is gevonden door de wetten van De Morgan toe te passen op antwoord 1.

int isMagisch(int vierkant[8][8]) {
    return !(!checkGetallen(vierkant) || !checkSomRijen(vierkant) || !checkSomKolommen(vierkant) || !checkSomDiagonalen(vierkant));
}

Antwoord 15.

Dit antwoord is een variant op antwoord 14. In plaats van de returnwaarde van elke functieaanroep logisch te inverteren wordt de returnwaarde van elke functie vergeleken met de waarde 1.

int isMagisch(int vierkant[8][8]) {
    return !(checkGetallen(vierkant) != 1 || checkSomRijen(vierkant) != 1 || checkSomKolommen(vierkant) != 1 || checkSomDiagonalen(vierkant) != 1);
}

Antwoord 16.

Bij dit antwoord wordt de lokale variabele ok geïnitialiseerd met de returnwaarde van de functieaanroep checkGetallen(vierkant). Daarna wordt de operator &= gebruikt om dit antwoord te combineren met de returnwaarde van de volgende functieaanroep. Het grote verschil met de antwoorden die gebruik maken van de operator && (zie bijvoorbeeld antwoord 1) is dat bij het gebuik van de operator &= alle vier de functies zullen worden aangeroepen. Dit antwoord is dus minder efficient dan antwoord 1.

int isMagisch(int vierkant[8][8]) {
    int ok = checkGetallen(vierkant);
    ok &= checkSomRijen(vierkant);
    ok &= checkSomKolommen(vierkant);
    ok &= checkSomDiagonalen(vierkant);
    return ok;
}

Antwoord 17.

Dit antwoord is gevonden door de wetten van De Morgan toe te passen op antwoord 16.

int isMagisch(int vierkant[8][8]) {
    int ok = !checkGetallen(vierkant);
    ok |= !checkSomRijen(vierkant);
    ok |= !checkSomKolommen(vierkant);
    ok |= !checkSomDiagonalen(vierkant);
    return !ok;
}

Antwoord 18.

Dit antwoord is in principe hetzelfde als antwoord 6. In dit geval wordt in plaats van de if ... else instructie gebruik gemaakt van de ? ... : operator.

int isMagisch(int vierkant[8][8]) {
    return checkGetallen(vierkant) ? checkSomRijen(vierkant) ? checkSomKolommen(vierkant) ? checkSomDiagonalen(vierkant) ? 1 : 0 : 0 : 0 : 0;
}

Antwoord 19.

Dit antwoord is gevonden door de wetten van De Morgan toe te passen op antwoord 18.

int isMagisch(int vierkant[8][8]) {
    return !checkGetallen(vierkant) ? 0 : !checkSomRijen(vierkant) ? 0 : !checkSomKolommen(vierkant) ? 0 : !checkSomDiagonalen(vierkant) ? 0 : 1;
}

Antwoord 20.

Bij dit antwoord wordt de lokale variabele check geïnitialiseerd met de returnwaarde van de functieaanroep checkGetallen(vierkant). Daarna wordt deze waarde vergeleken met de returnwaarden van de andere functieaanroepen. Als die allemaal gelijk zijn aan de waarde van check dan wordt de waarde van check teruggegeven. Anders wordt een 0 teruggegeven. De functie isMagisch kan dus alleen de waarde 1 teruggeven als alle functieaanroepen de waarde 1 hebben teruggeven. In alle andere gevallen wordt de waarde 0 teruggegeven.

int isMagisch(int vierkant[8][8]) {
    int check = checkGetallen(vierkant);
    if (check == checkSomRijen(vierkant) && check == checkSomKolommen(vierkant) && check == checkSomDiagonalen(vierkant)) {
        return check;
    }
    return 0;
}

Antwoord 21.

Dit antwoord is gevonden door de wetten van De Morgan toe te passen op antwoord 20.

int isMagisch(int vierkant[8][8]) {
    int check = checkGetallen(vierkant);
    if (check != checkSomRijen(vierkant) || check != checkSomKolommen(vierkant) || check != checkSomDiagonalen(vierkant)) {
        return 0;
    }
    return check;
}