Bash simplified sudoku

孤人 提交于 2019-11-29 13:03:38
$ awk '
    function check(num) {

        return num != 45 ? 1 : 0;
    }
    {
        row = 0;
        for (i = 1; i <= 9; i++) {
            row += $i;
            col[i] += $i;
        }
        if (check(row) > 0) {
            errors[++error_len] = sprintf("error in line %s: %s", FNR, $0);
        }
    }
    END {
        for (i = 1; i <= 9; i++) {
            if (check(row) > 0) {
                errors[++error_len] = sprintf("error in column %s: %s", i, col[i]);
            }
        }
        if (error_len) {
            for (i = 0; i <= error_len; i++) {
                print(errors[i]);
            }
        }
        else {
            print("all good");
        }
    }
' sudoku
error in line 4: 6 7 1 4 8 2 6 9 3

$ cat sudoku
8 1 2 9 7 4 3 6 5  
9 3 4 6 5 1 7 8 2  
7 6 5 8 2 3 9 4 1  
6 7 1 4 8 2 6 9 3 <-- see the 6 here thats an error:
2 8 9 3 6 5 4 1 7  
6 4 3 7 1 9 2 5 8
1 9 6 5 3 7 8 2 4  
3 2 8 1 4 6 5 7 9  
4 5 7 2 9 8 1 3 6

It's easy if you transpose the matrix first using awk, then just loop over it the same way you did for the columns. file: transpose.awk

#! /bin/sh
# Transpose a matrix: assumes all lines have same number
# of fields

exec awk '
NR == 1 {
    n = NF
    for (i = 1; i <= NF; i++)
        row[i] = $i
    next
}
{
    if (NF > n)
        n = NF
    for (i = 1; i <= NF; i++)
        row[i] = row[i] " " $i
}
END {
    for (i = 1; i <= n; i++)
        print row[i]
}' ${1+"$@"}

for a in {1..9}; do var=$(cut -d ' ' -f ${a} sudoku.txt | sort -n | uniq -d); ((${var:-0} > 0)) && echo "Column $a is bad, duplicate ${var}'s."; done

for a in {1..9}; do var=$(transpose.awk sudoku.txt | cut -d ' ' -f ${a} | sort -n | uniq -d); ((${var:-0} > 0)) && echo "Row $a is bad, duplicate ${var}'s."; done

Run on sample file sudoku.txt:

5 3 4 6 7 8 9 1 2
6 7 2 1 9 5 3 4 8
1 3 8 3 4 2 5 6 7
8 5 9 7 6 1 4 2 3
4 2 6 8 5 3 7 9 1
7 1 3 9 2 4 8 5 6
9 6 1 1 3 7 2 8 4
2 8 7 4 1 9 6 3 5
3 4 5 2 8 6 1 7 8

Column 2 is bad, duplicate 3's.
Column 4 is bad, duplicate 1's.
Column 9 is bad, duplicate 8's.
Row 3 is bad, duplicate 3's.
Row 7 is bad, duplicate 1's.
Row 9 is bad, duplicate 8's.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!