#include <stdio.h>

int leesin(int s[][9]) {
    char naam[80];
    FILE* invoer;
    int r, k;
    printf("Geef de naam van de invoerbestand: ");
    if (scanf("%79s", naam)!=1) {
        printf("Fout bij inlezen bestandsnaam.\n");
        return 0;
    }
    invoer=fopen(naam, "r");
    if (invoer==0) {
        printf("De file %s kan  niet gevonden of niet gelezen worden.\n", naam);
        return 0;
    }
    for (r=0; r<9; r++) {
        for (k=0; k<9; k++) {
            if (fscanf(invoer, "%d", &s[r][k])!=1) {
                printf("Fout bij inlezen %s.\n"
                       "Dit bestand moet 81 getallen van een sudoku bevatten.\n"
                       "Lege plaatsen moeten met een 0 worden aangegeven.", naam);
                fclose(invoer);
                return 0;
            }
            if (s[r][k]<0 || s[r][k]>9) {
                printf("Fout bij inlezen %s.\n"
                       "Dit bestand moet 81 getallen tussen 0 en 10 van een sudoku bevatten.\n"
                       "Lege plaatsen moeten met een 0 worden aangegeven.", naam);
                fclose(invoer);
                return 0;
            }
        }
    }
    fclose(invoer);
    return 1;
}

void drukaf(int s[][9]) {
    int r, k;
    for (r=0; r<9; r++) {
        for (k=0; k<9; k++) {
            printf("%d ", s[r][k]);
        }
        printf("\n");
    }
}

int controleer(int s[][9]) {
    int r, k, b;
    // rij
    for (r=0; r<9; r++) {
        int afvinklijst[9]={0};
        for (k=0; k<9; k++) {
            if (s[r][k]!=0 && ++afvinklijst[s[r][k]-1]>1) {
                return 0;
            }
        }
    }
    // kolom
    for (k=0; k<9; k++) {
        int afvinklijst[9]={0};
        for (r=0; r<9; r++) {
            if (s[r][k]!=0 && ++afvinklijst[s[r][k]-1]>1) {
                return 0;
            }
        }
    }
    // blok
    for (b=0; b<9; b++) {
        int afvinklijst[9]={0};
        int rb=b/3 * 3;
        int kb=b%3 * 3;
        for (r=rb; r<rb+3; r++) {
            for (k=kb; k<kb+3; k++) {
                if (s[r][k]!=0 && ++afvinklijst[s[r][k]-1]>1) {
                    return 0;
                }
            }
        }
    }
    return 1;
}

int losop(int s[][9]) {
    int probeer(int [][9], int);
    int i;
    for (i=1; i<10; i++) {
        if (probeer(s, i)==1) {
            return 1;
        }
    }
    return 0;
}

int probeer(int s[][9], int p) {
    int r, k, i;
    for (r=0; r<9; r++) {
        for (k=0; k<9; k++) {
            if (s[r][k]==0) {
                s[r][k]=p;
                if (controleer(s)==0) {
                    s[r][k]=0;
                    return 0;
                }
                for (i=1; i<10; i++) {
                    if (probeer(s, i)==1) {
                        return 1;
                    }
                }
                s[r][k]=0;
                return 0;
            }
        }
    }
    return 1;
}

int main() {
    int sudoku[9][9];
    int leesin(int [][9]);
    void drukaf(int [][9]);
    int controleer(int [][9]);
    int losop(int [][9]);
    
    if (leesin(sudoku)) {
        if (controleer(sudoku)==0) { 
            printf("Deze sudoku is niet geldig!\n");
        }
        if (losop(sudoku)==0) {
            printf("Deze sudoku kun je niet oplossen!\n");
        }
        drukaf(sudoku);                  
    }

    fflush(stdin);
    getchar();
    return 0;
}
