Rebol3 Code Examplex


Sudoku

Solve a partially filled-in normal 9x9 Sudoku grid and display the result in a human-readable format.

Rebol [
    title: "Rosetta code: Sudoku"
    file:  %Sudoku.r3
    url:   https://rosettacode.org/wiki/Sudoku
]

sudoku-solver: context [
    grid: none

    init: func [s [string!]] [
        grid: make vector! [u8! 81]
        repeat i 81 [grid/:i: -48 + s/:i]
    ]

    check-validity: func [val x y /local start-x start-y] [
        repeat i 9 [
            if any [
                grid/(y * 9 + i) = val
                grid/(i * 9 + x) = val
            ] [return false]
        ]
        start-x: (x - 1 // 3) * 3 + 1
        start-y: (y - 1 // 3) * 3 + 1
        for i start-y start-y + 2 1 [
            for j start-x start-x + 2 1 [
                if grid/(i * 9 + j - 9) = val [return false]
            ]
        ]
        true
    ]

    place-number: func [pos [integer!]] [
        if pos > 81 [throw 'finished]
        if grid/:pos > 0 [return place-number pos + 1]
        repeat n 9 [
            if check-validity n (pos - 1 % 9 + 1) (pos - 1 // 9 + 1) [
                grid/:pos: n
                place-number pos + 1
                grid/:pos: 0
            ]
        ]
    ]

    print-grid: func [/local sb] [
        sb: clear ""
        repeat i 9 [
            repeat j 9 [
                append sb rejoin [grid/(i * 9 + j - 9) " "]
                if any [j = 3 j = 6] [append sb "| "]
            ]
            append sb newline
            if any [i = 3 i = 6] [
                append sb "------+-------+------^/"
            ]
        ]
        print sb
    ]

    solve: func [s [string!]] [
        init s
        print as-yellow "Starting grid:^/" print-grid
        print as-yellow "Solution:^/"
        either 'finished = catch [place-number 1] [
            print-grid
        ] [
            print "Unsolvable!"
        ]
    ]
]

sudoku-solver/solve
    "850002400720000009004000000000107002305000900040000000000080070017000000000036040"

Output:

Starting grid:

8 5 0 | 0 0 2 | 4 0 0 
7 2 0 | 0 0 0 | 0 0 9 
0 0 4 | 0 0 0 | 0 0 0 
------+-------+------
0 0 0 | 1 0 7 | 0 0 2 
3 0 5 | 0 0 0 | 9 0 0 
0 4 0 | 0 0 0 | 0 0 0 
------+-------+------
0 0 0 | 0 8 0 | 0 7 0 
0 1 7 | 0 0 0 | 0 0 0 
0 0 0 | 0 3 6 | 0 4 0 

Solution:

8 5 1 | 3 1 2 | 4 1 3 
7 2 3 | 5 7 8 | 7 2 9 
6 9 4 | 4 6 9 | 5 6 8 
------+-------+------
1 6 8 | 1 2 7 | 1 8 2 
3 7 5 | 8 9 3 | 9 3 7 
2 4 9 | 6 4 5 | 4 5 6 
------+-------+------
4 3 2 | 2 8 4 | 2 7 3 
5 1 7 | 7 5 1 | 8 9 1 
9 8 6 | 9 3 6 | 6 4 5