andere opgaven: acht koninginnen | boter, kaas en eieren | logiquiz | sudoku | laatste wint

Sudoku puzzel

Inhoud:
de puzzel
benadering
programma afloop
invoer
voorbeeld
code

Hoe zelfs de moeilijkste sudoku puzzel op te lossen (met een computer) ?

De puzzel:

De bedoeling van een sudoku puzzel is de 9x9 matrix zodanig in te vullen met de getallen 1 t/m 9 dat in iedere rij, kolom of 3x3-kwadrant die getallen maar èèn keer voorkomen. Een aantal posities is al ingevuld.
De eenvoudige sudoku's kunnen worden opgelost door een kolom/rij/kwadrant te vergelijken, waarbij er nog maar een positie overblijft voor een bepaald getal. Bij de moeilijkere puzzels zijn andere strategiën nodig, bijvoorbeeld uitsluiting over meerdere kolommen/rijen/kwadranten.

Benadering:

De computer leent zich voor een andere aanpak. Aanvankelijk krijgt ieder vakje in de matrix alle mogelijke opties 1-9 toegewezen. Dan worden de reeds toegewezen (gevulde) vakjes gebruikt om de opties uit de aangrenzende vakjes weg te strepen. De resterende opties worden nu een voor een uitgeprobeerd, waarbij direkt de gekozen optie wordt doorgerekend in de aangrenzende vakjes. Soms (vaak) blijkt een ingeslagen weg niet te leiden tot een oplossing, waardoor moet worden terug gevallen naar een eerdere keuze. Dit wordt 'backtracking' genoemd. Uiteindelijk resulteert dit in de (een) oplossing. Hiermee zijn zelfs de moeilijkste sudoku's op te lossen.

Programma afloop:

Allereerst word de interne nummering van de vakjes van de sudoku bepaald ('rijen', 'kolommen', 'blokken'), en ook van ieder vakje alle aangrenzende vakjes opgesomd, de zgn. 'buren'. Dan wordt voor ieder vakje de kandidaten bepaald: _genereer_kandidaten() (een kandidaat is een mogelijke uitkomst voor een vakje).
Nu wordt voor ieder vakje dat nog kandidaten heeft, doorgerekend of zo'n kandidaat niet een conflict zal geven met een van zijn buren is_geldige_zet(), maar voordat deze kandidaat daadwerkelijk wordt geplaatst, wordt deze toestand van de sudoku tijdelijk opgeslagen op een stapel (vergelijk dit met een stapel borden in een restaurant), stapel_append().
Als een latere zet verkeerd uitpakt, wordt teruggevallen naar een andere kandidaat voor dat vakje; of indien er geen kandidaten meer zijn voor dat vakje, wordt de vorige toestand van de stapel gehaald stapel.pop().
Bij iedere zet zal worden bekeken of de sudoku is opgelost, is_opgelost(), waardoor de zoeklus ('while ...') zal worden onderbroken.

Invoeren van een puzzel:

Invoeren van een puzzel kan door de gegeven getallen/vakjes in èèn lange reeks karakters te schrijven: voor een leeg vakje een niet-cijfer, voor een gevuld vakje het cijfer; spaties worden genegeerd. Van links naar rechts, van boven naar beneden.
Voor bovenstaand voorbeeld wordt dit:
3.65.84.. 52....... .87....31 ..3.1..8. 9..863..5 .5..9.6.. 13....25. .......74 ..52.63..
 
In de code zijn ook een aantal voorbeelden gegeven.

De code



#usr/bin/env python
# -*- coding: utf-8 -*-
# 
# (c) Mark Nauta
#
# lees het volledige verhaal: https://nadro.nl/mark/puzzels/sudoku.html  

from copy import deepcopy
from datetime import datetime, timedelta
import re

buren = [ [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 18, 19, 20, 27, 36, 45, 54, 63, 72], [0,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 18, 19, 20, 28, 37, 46, 55, 64, 73],  [0,  1,  3,  4,  5,  6,  7,  8,  9, 10, 11, 18, 19, 20, 29, 38, 47, 56, 65, 74], [0,  1,  2,  4,  5,  6,  7,  8, 12, 13, 14, 21, 22, 23, 30, 39, 48, 57, 66, 75],   [0,  1,  2,  3,  5,  6,  7,  8, 12, 13, 14, 21, 22, 23, 31, 40, 49, 58, 67, 76], [0,  1,  2,  3,  4,  6,  7,  8, 12, 13, 14, 21, 22, 23, 32, 41, 50, 59, 68, 77],   [0,  1,  2,  3,  4,  5,  7,  8, 15, 16, 17, 24, 25, 26, 33, 42, 51, 60, 69, 78], [0,  1,  2,  3,  4,  5,  6,  8, 15, 16, 17, 24, 25, 26, 34, 43, 52, 61, 70, 79],   [0,  1,  2,  3,  4,  5,  6,  7, 15, 16, 17, 24, 25, 26, 35, 44, 53, 62, 71, 80], [0,  1,  2, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 27, 36, 45, 54, 63, 72],   [0,  1,  2,  9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 28, 37, 46, 55, 64, 73], [0,  1,  2,  9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 29, 38, 47, 56, 65, 74],   [3,  4,  5,  9, 10, 11, 13, 14, 15, 16, 17, 21, 22, 23, 30, 39, 48, 57, 66, 75], [3,  4,  5,  9, 10, 11, 12, 14, 15, 16, 17, 21, 22, 23, 31, 40, 49, 58, 67, 76],   [3,  4,  5,  9, 10, 11, 12, 13, 15, 16, 17, 21, 22, 23, 32, 41, 50, 59, 68, 77], [6,  7,  8,  9, 10, 11, 12, 13, 14, 16, 17, 24, 25, 26, 33, 42, 51, 60, 69, 78],   [6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 17, 24, 25, 26, 34, 43, 52, 61, 70, 79], [6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 24, 25, 26, 35, 44, 53, 62, 71, 80],   [0,  1,  2,  9, 10, 11, 19, 20, 21, 22, 23, 24, 25, 26, 27, 36, 45, 54, 63, 72], [0,  1,  2,  9, 10, 11, 18, 20, 21, 22, 23, 24, 25, 26, 28, 37, 46, 55, 64, 73],   [0,  1,  2,  9, 10, 11, 18, 19, 21, 22, 23, 24, 25, 26, 29, 38, 47, 56, 65, 74], [3,  4,  5, 12, 13, 14, 18, 19, 20, 22, 23, 24, 25, 26, 30, 39, 48, 57, 66, 75],   [3,  4,  5, 12, 13, 14, 18, 19, 20, 21, 23, 24, 25, 26, 31, 40, 49, 58, 67, 76], [3,  4,  5, 12, 13, 14, 18, 19, 20, 21, 22, 24, 25, 26, 32, 41, 50, 59, 68, 77],    [6,  7,  8, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 33, 42, 51, 60, 69, 78], [6,  7,  8, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 34, 43, 52, 61, 70, 79],   [6,  7,  8, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 35, 44, 53, 62, 71, 80], [0,  9, 18, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 46, 47, 54, 63, 72],  [1, 10, 19, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 46, 47, 55, 64, 73], [2, 11, 20, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 46, 47, 56, 65, 74],   [3, 12, 21, 27, 28, 29, 31, 32, 33, 34, 35, 39, 40, 41, 48, 49, 50, 57, 66, 75], [4, 13, 22, 27, 28, 29, 30, 32, 33, 34, 35, 39, 40, 41, 48, 49, 50, 58, 67, 76], [5, 14, 23, 27, 28, 29, 30, 31, 33, 34, 35, 39, 40, 41, 48, 49, 50, 59, 68, 77], [6, 15, 24, 27, 28, 29, 30, 31, 32, 34, 35, 42, 43, 44, 51, 52, 53, 60, 69, 78], [7, 16, 25, 27, 28, 29, 30, 31, 32, 33, 35, 42, 43, 44, 51, 52, 53, 61, 70, 79], [8, 17, 26, 27, 28, 29, 30, 31, 32, 33, 34, 42, 43, 44, 51, 52, 53, 62, 71, 80], [0,  9, 18, 27, 28, 29, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 54, 63, 72], [1, 10, 19, 27, 28, 29, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 55, 64, 73], [2, 11, 20, 27, 28, 29, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 56, 65, 74], [3, 12, 21, 30, 31, 32, 36, 37, 38, 40, 41, 42, 43, 44, 48, 49, 50, 57, 66, 75], [4, 13, 22, 30, 31, 32, 36, 37, 38, 39, 41, 42, 43, 44, 48, 49, 50, 58, 67, 76], [5, 14, 23, 30, 31, 32, 36, 37, 38, 39, 40, 42, 43, 44, 48, 49, 50, 59, 68, 77], [6, 15, 24, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 51, 52, 53, 60, 69, 78], [7, 16, 25, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 51, 52, 53, 61, 70, 79], [8, 17, 26, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 51, 52, 53, 62, 71, 80], [0,  9, 18, 27, 28, 29, 36, 37, 38, 46, 47, 48, 49, 50, 51, 52, 53, 54, 63, 72], [1, 10, 19, 27, 28, 29, 36, 37, 38, 45, 47, 48, 49, 50, 51, 52, 53, 55, 64, 73], [2, 11, 20, 27, 28, 29, 36, 37, 38, 45, 46, 48, 49, 50, 51, 52, 53, 56, 65, 74], [3, 12, 21, 30, 31, 32, 39, 40, 41, 45, 46, 47, 49, 50, 51, 52, 53, 57, 66, 75], [4, 13, 22, 30, 31, 32, 39, 40, 41, 45, 46, 47, 48, 50, 51, 52, 53, 58, 67, 76], [5, 14, 23, 30, 31, 32, 39, 40, 41, 45, 46, 47, 48, 49, 51, 52, 53, 59, 68, 77], [6, 15, 24, 33, 34, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, 60, 69, 78], [7, 16, 25, 33, 34, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 53, 61, 70, 79], [8, 17, 26, 33, 34, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 62, 71, 80], [0,  9, 18, 27, 36, 45, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 72, 73, 74], [1, 10, 19, 28, 37, 46, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 72, 73, 74], [2, 11, 20, 29, 38, 47, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 72, 73, 74], [3, 12, 21, 30, 39, 48, 54, 55, 56, 58, 59, 60, 61, 62, 66, 67, 68, 75, 76, 77], [4, 13, 22, 31, 40, 49, 54, 55, 56, 57, 59, 60, 61, 62, 66, 67, 68, 75, 76, 77], [5, 14, 23, 32, 41, 50, 54, 55, 56, 57, 58, 60, 61, 62, 66, 67, 68, 75, 76, 77], [6, 15, 24, 33, 42, 51, 54, 55, 56, 57, 58, 59, 61, 62, 69, 70, 71, 78, 79, 80], [7, 16, 25, 34, 43, 52, 54, 55, 56, 57, 58, 59, 60, 62, 69, 70, 71, 78, 79, 80], [8, 17, 26, 35, 44, 53, 54, 55, 56, 57, 58, 59, 60, 61, 69, 70, 71, 78, 79, 80], [0,  9, 18, 27, 36, 45, 54, 55, 56, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], [1, 10, 19, 28, 37, 46, 54, 55, 56, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], [2, 11, 20, 29, 38, 47, 54, 55, 56, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 74], [3, 12, 21, 30, 39, 48, 57, 58, 59, 63, 64, 65, 67, 68, 69, 70, 71, 75, 76, 77], [4, 13, 22, 31, 40, 49, 57, 58, 59, 63, 64, 65, 66, 68, 69, 70, 71, 75, 76, 77], [5, 14, 23, 32, 41, 50, 57, 58, 59, 63, 64, 65, 66, 67, 69, 70, 71, 75, 76, 77], [6, 15, 24, 33, 42, 51, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 78, 79, 80], [7, 16, 25, 34, 43, 52, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 78, 79, 80], [8, 17, 26, 35, 44, 53, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 78, 79, 80], [0,  9, 18, 27, 36, 45, 54, 55, 56, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80], [1, 10, 19, 28, 37, 46, 54, 55, 56, 63, 64, 65, 72, 74, 75, 76, 77, 78, 79, 80], [2, 11, 20, 29, 38, 47, 54, 55, 56, 63, 64, 65, 72, 73, 75, 76, 77, 78, 79, 80], [3, 12, 21, 30, 39, 48, 57, 58, 59, 66, 67, 68, 72, 73, 74, 76, 77, 78, 79, 80], [4, 13, 22, 31, 40, 49, 57, 58, 59, 66, 67, 68, 72, 73, 74, 75, 77, 78, 79, 80], [5, 14, 23, 32, 41, 50, 57, 58, 59, 66, 67, 68, 72, 73, 74, 75, 76, 78, 79, 80], [6, 15, 24, 33, 42, 51, 60, 61, 62, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80], [7, 16, 25, 34, 43, 52, 60, 61, 62, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80], [8, 17, 26, 35, 44, 53, 60, 61, 62, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79] ]
rijen =  [ [ 0,  1,  2,  3,  4,  5,  6,  7,  8], [ 9, 10, 11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24, 25, 26],    
        [27, 28, 29, 30, 31, 32, 33, 34, 35], [36, 37, 38, 39, 40, 41, 42, 43, 44], [45, 46, 47, 48, 49, 50, 51, 52, 53], 
        [54, 55, 56, 57, 58, 59, 60, 61, 62], [63, 64, 65, 66, 67, 68, 69, 70, 71], [72, 73, 74, 75, 76, 77, 78, 79, 80] ]
kolommen =  [ [ 0,  9, 18, 27, 36, 45, 54, 63, 72], [ 1, 10, 19, 28, 37, 46, 55, 64, 73], [ 2, 11, 20, 29, 38, 47, 56, 65, 74], 
        [ 3, 12, 21, 30, 39, 48, 57, 66, 75], [ 4, 13, 22, 31, 40, 49, 58, 67, 76], [ 5, 14, 23, 32, 41, 50, 59, 68, 77], 
        [ 6, 15, 24, 33, 42, 51, 60, 69, 78], [ 7, 16, 25, 34, 43, 52, 61, 70, 79], [ 8, 17, 26, 35, 44, 53, 62, 71, 80] ] 
blokken =  [ [ 0,  1,  2,  9, 10, 11, 18, 19, 20], [ 3,  4,  5, 12, 13, 14, 21, 22, 23], [ 6,  7,  8, 15, 16, 17, 24, 25, 26], 
        [27, 28, 29, 36, 37, 38, 45, 46, 47], [30, 31, 32, 39, 40, 41, 48, 49, 50], [33, 34, 35, 42, 43, 44, 51, 52, 53], 
        [54, 55, 56, 63, 64, 65, 72, 73, 74], [57, 58, 59, 66, 67, 68, 75, 76, 77], [60, 61, 62, 69, 70, 71, 78, 79, 80] ] 
rkb_indx = [ [0,0,0], [0,1,0], [0,2,0], [0,3,1], [0,4,1], [0,5,1], [0,6,2], [0,7,2], [0,8,2], [1,0,0], [1,1,0], [1,2,0], [1,3,1], [1,4,1], [1,5,1], [1,6,2], [1,7,2], [1,8,2], [2,0,0], [2,1,0], [2,2,0], [2,3,1], [2,4,1], [2,5,1], [2,6,2], [2,7,2], [2,8,2], [3,0,3], [3,1,3], [3,2,3], [3,3,4], [3,4,4], [3,5,4], [3,6,5], [3,7,5], [3,8,5], [4,0,3], [4,1,3], [4,2,3], [4,3,4], [4,4,4], [4,5,4], [4,6,5], [4,7,5], [4,8,5], [5,0,3], [5,1,3], [5,2,3], [5,3,4], [5,4,4], [5,5,4], [5,6,5], [5,7,5], [5,8,5], [6,0,6], [6,1,6], [6,2,6], [6,3,7], [6,4,7], [6,5,7], [6,6,8], [6,7,8], [6,8,8], [7,0,6], [7,1,6], [7,2,6], [7,3,7], [7,4,7], [7,5,7], [7,6,8], [7,7,8], [7,8,8], [8,0,6], [8,1,6], [8,2,6], [8,3,7], [8,4,7], [8,5,7], [8,6,8], [8,7,8], [8,8,8] ] 

class Sudoku():
    def __init__(self, karakters, titel=None):
        self._start_tijd = datetime.now()
        self.titel = titel
        self.opgave = [ int(x) for x in re.sub(r'[^\d]', '0', re.sub(r'\s', '', karakters)) ]
        self.stapel = []
        kandidaten = [ [ k for k in range(1,10) if k not in [ self.opgave[buur] for buur in buren[veld] if self.opgave[buur] > 0 ] ] for veld in range(81) ]
        self.stapel.append(kandidaten)
        self.duur = timedelta()

    def __str__(self):
        return '\n'.join( [ ''.join( [ str(self.opgave[j*9+i]) for i in range(9) ] ) for j in range(9) ] ).replace('0', '.')

    def is_opgelost(self):
        for blok in rijen+kolommen+blokken:
            reeks = ''.join([ str(self.stapel[-1][blok[i]][0]) for i in range(9) if len(self.stapel[-1][blok[i]]) == 1 ])
            if ''.join(sorted(reeks)) != '123456789':
                return False
        self.duur = datetime.now()-self._start_tijd
        return True

    def valide_invoer(self, kandidaat, veld):
        if kandidaat not in self.stapel[-1][veld]:
            return False
        return kandidaat not in ([ self.stapel[-1][buur][0] for buur in buren[veld] if len(self.stapel[-1][buur])==1 ])
        
    def los_op(self):
        cel_indx=0
        while not self.is_opgelost():
            kandidaat = self.stapel[-1][cel_indx][0]
            if self.valide_invoer(kandidaat, cel_indx):
                self.stapel.append( deepcopy(self.stapel[-1]) )
                for buur in buren[cel_indx]:
                    if kandidaat in self.stapel[-1][buur]:
                        self.stapel[-1][buur].remove(kandidaat)
                cel_indx += 1
            else:
                while len(self.stapel[-1][cel_indx]) == 1:
                    self.stapel.pop()
                    cel_indx -= 1
                self.stapel[-1][cel_indx]=self.stapel[-1][cel_indx][1:]

        for cel_indx in range(81): 
            self.opgave[cel_indx] = self.stapel[-1][cel_indx][0]

if __name__ == '__main__':
    p = [ [] ] * 99
    p[0]= ('5....31.. ...7..... ..9...576 ....2493. 9...6...8 .4.89.... 162...3.. .9...1... ..56....9', '0')
    p[1]= ('3.65.84.. 52....... .87....31 ..3.1..8. 9..863..5 .5..9.6.. 13....25. .......74 ..52.63..', 'website')
    p[2]= ('.......34 ...7..18. ..76.4.2. 5........ ..4..8... .2...931. .19.75... .8.3...4. .........', '2')
    p[3]= ('2......76 149...2.8 57...8.49 .2...4.65 894765..1 7..3.1..4 ....1.6.7 9.3..7.8. 6574.2...', '3')
    p[4]= ('......... .....7.25 ..9.8.... ...5.3... ..6...9.. .1....... 5......37 ..8.9.... ....6...1', '4')
    p[5]= ('......... .....4.82 ..6.5.... ...2.9... ..3...6.. .7....... 2......94 ..5.6.... ....3...7', '4!')
    p[6]= ('......... .....3.85 ..1.2.... ...5.7... ..4...1.. .9....... 5......73 ..2.1.... ....4...9', '4!!')
    p[7]= ('.9..57... 2.......5 .....4..6 .6....... ..5.634.. 3..9.8... .3..7..8. .27..9... .4.8.1.5.', 'hard')
    p[8]= ('...3..... ..84.9... 3..56...9 69...7... .1..8..7. ....1..4. 7......82 ......... .6..3.75.', 'expert')
    p[9]= ('638...5.. .2...731. ...5....6 .1...6... 2..8.4..1 ...1...5. 9....1... .653...9. ..1...428', 'expert')
    p[10]=('123...7.. .4...825. ...7....1 .5...1... 4..3.9..5 ...5...7. 6....5... .172...6. ..5...943', 'expert') 
    p[11]=('987...3.. .6...285. ...3....9 .5...9... 6..7.1..5 ...5...3. 4....5... .938...4. ..5...167', 'expert') 
    p[12]=('934218765 ...476398 876359241 .498356.7 78.642.39 6.31978.4 .627849.3 4.8923.76 397561482', '8')
    p[13]=('..9748... 7........ .2.1.9... ..7...24. .64.1.59. .98...3.. ...8.3.2. ........6 ...2759..', '9')
    p[14]=('.8....2.. ....84.9. ..632..1. .97....8. 8..9.3..2 .1....95. .7..458.. .3.71.... ..8....4.', '10')
    p[15]=('..4..16.. 29...7.8. ....6..4. ..7.5..9. .5...316. 3.26..4.. 8..9..... .....65.. .29......', 'ultra 6*')    
    p[16]=('.7..8.6.. .3....9.. .58.4...7 ..9..2... ......... 26.37.8.. .....4.2. .462...7. 8.59...6.', 'ultra 7*') 
    p[17]=('78..9...6 ...7....3 .5......4 .7.51.2.. 8...6..4. ...9....7 .1.6....5 ..4...3.. 5...2..9.', 'ultra 7*') 
    p[18]=('.....7... 9.61..... ..12..74. 7....4..9 .9.8..1.. .3..1...7 ..7.2.5.4 .....12.. .25.3....', 'ultra 7*') 
    p[19]=('..37..8.. ..8.4.7.. 1....6.5. ....6..9. .....52.8 8...7...5 6.....5.7 ....2..13 29.......', 'ultra 7*') 
    p[20]=('51....9.7 2.....3.. ...3..... .6.....91 ...9...8. ...17..2. ..4..2... 1...6..4. ..9..85..', 'ultra 7*') 
    p[22]=('...57...9 ..8...6.7 .9...1... 9.62..... 52....... ....1...5 2.7.4.1.. .3...7.8. 8.9...2..', 'ultra 7* 13') 
    p[23]=('.8..2..6. ..6.18.73 ..7...2.. ........7 5.2...13. .....7..8 .4.6...9. 2..8..... 9..5.....', 'ultra 7* 15') 
    p[30]=('8........ ..36..... .7..9.2.. .5...7... ....457.. ...1...3. ..1....68 ..85...1. .9....4..', 'world\'s toughest sudoku by Arto Inkala - original')
    p[31]=('1........ ..67..... .4..9.3.. .5...4... ....854.. ...2...6. ..2....71 ..15...2. .9....8..', 'world\'s toughest sudoku by Arto Inkala - sorted')
    p[32]=('9........ ..43..... .6..1.7.. .5...6... ....156.. ...8...4. ..8....39 ..95...8. .1....2..', 'world\'s toughest sudoku by Arto Inkala - sorted reversed')

    puzzel_nummer = 1
    opgave = Sudoku(p[puzzel_nummer][0], p[puzzel_nummer][1])
    print(opgave)
    opgave.los_op()
    print('oplossen duurde: {}'.format(opgave.duur, ) )
    print(opgave)