; Brian Alliet ; Programming Language Theory ; 4005-710-01 ; Copyright 2005 Brian Alliet ; Sudoku stuff for Homework 2 (define (backtrack grid) (let ((p (undecided grid))) (if (not p) (list grid) ; it is solved, return this as a solutin (apply append (map (lambda (x) (solve (substitute x p grid))) (list-ref grid p)))))) (define (solve grid) (let ((grid2 (simplify grid))) (if (memq #f grid2) '() ; if there are "impossible" cells there is no solution (backtrack grid2)))) ; if not, backtrack (which won't do anything for simple puzzles) ; split-at splits a list in two at position n. The result is a ; pair containing the two lists ; (split-at 3 '(1 2 3 4 5)) => '((1 2 3) . (4 5)) (define (split-at n xs) (if (null? xs) (cons '() '()) (if (= 0 n) (cons '() xs) (let ((rest (split-at (- n 1) (cdr xs)))) (cons (cons (car xs) (car rest)) (cdr rest)))))) ; Reduce uses prune to eliminate impossible candidates from the grid (define (reduce grid) (letrec ; Reduce-one reduces a single element then recurses on the rest ; of the grid ((reduce-one (lambda (n xs) (if (null? xs) ; if we hit the end of the grid we're done '() (let* ((x (car xs)) ; save the current cell ; if this cell is 0 then replace it with all possible ; candidates (x (if (eqv? 0 x) '(1 2 3 4 5 6 7 8 9) x))) ; cons the result on to the results of the rest of ; the grid (cons ; if it is a pair (list) we have to prune it ; if not, return it unmodified (if (pair? x) (let* ; Split the grid at the current element ((split (split-at n grid)) ; prune the current element (pruned (prune (car split) x (cddr split)))) (cond ; if we eliminated everything we're screwed ; we'll use #f to represent "Impossible" ((null? pruned) #f) ; If the pruned list has a single element ; then it is a known correct value ((null? (cdr pruned)) (car pruned)) ; If not, just return the new pruned list (else pruned))) x) ; call ourselved on the rest of the list (reduce-one (+ n 1) (cdr xs)))))))) (let ; start off reducing the whole grid (which starts with element 0) ((new (reduce-one 0 grid)) (cell-length (lambda (cell) (if cell (if (pair? cell) (length cell) 1) 0)))) ; if we make some changes make a second pass (if (equal? (map cell-length grid) (map cell-length new)) grid (reduce new))))) ; END PUBLIC ;checks to see if item is at position in vector - returns true or false... (define in-vector-at-position? (lambda (vector item position) (cond ( (equal? (vector? vector) #f) #f) (else (if (equal? (vector-ref vector position) item) #t #f))))) (define ok??-helper (lambda (digit position cells elements) (cond ((null? cells) #t) ((equal? position (car cells)) (ok??-helper digit position (cdr cells) elements)) ;skips over position if it is the current "car" (else (if (equal? (in-vector-at-position? elements digit (car cells)) #t ) ;if index at car of cells is in the vector at that index, stop and return false since it was found #f ( ok??-helper digit position (cdr cells) elements)))))) ; if not found at current index, continue to loop through all indexes ;is true exactly if the (non-zero) digit has not been entered into certain cells of the vector elements. ;false if it does exist, although position will be skipped if it is given within vector ;The list cells contains the indices to check; ;however, position is the index of digit in elements and this value must be skipped when checking out cells. (define ok?? (lambda (digit position cells elements) ;check to make sure values are appropriate (cond ( (equal? (or (equal? (null? cells) #t) (equal? (vector? elements) #f)) #t) #f) ;not indices to check so can't exist or not vector as incoming (else (ok??-helper digit position cells elements))))) ;;activates checking helper function ;ok-question.scm ;Mike Mertsock, PLT 20051 ;Provides the ok? function for the Suduko group project ;usage: see documentation for ok? -- at bottom of file ;test harness: ; ok-question-test.scm provides a test harness ; for working within the scope of the finished ok? and ok?? ; functions. ;Helper for ok?-checkgroup. ;Calls ok?? ;Checks if a particular index within the Suduko solution ;is legal within the given group of elements. ;param velements: a VECTOR of the Suduko solution ;param group: an item from rows/columns/boxes: a list ; indexes into the velements vector. (define ok?-checki (lambda (index group velements) (if (number? (vector-ref velements index)) (if (> (vector-ref velements index) 0) (ok?? (vector-ref velements index) index group velements) #t ;ignore zero entries ) #t ;ignore non-numeric (list) entries ) )) ;Helper for ok?-checkgroups. ;Checks if all of finalized solution elements are legal ;within a single specified group (row/column/box). ;param velements: a VECTOR of the Suduko solution ;param group: a list representing one row/col/box of indexes (define ok?-checkgroup (lambda (velements group) ;for each index in group (letrec ((check-partial (lambda (grouppart) (if (null? grouppart) #t ;checked everything successfully (if (not (ok?-checki (car grouppart) group velements)) #f ;one element failed. stop now and return #f (check-partial (cdr grouppart)) ) ) ))) (check-partial group) ) )) ;Helper for ok?. Breaks up the checking into examining ;elements' legality among groups (rows/cols/boxes). ;param velements: a VECTOR of the Suduko solution ;param grouplist: a list of groups (such as the groups var) ;returns: #t if all of velements passes testing for each group (define ok?-checkgroups (lambda (velements grouplist) ;things are ok if all checks for this group are ok ;and all checks for the remaining groups are ok. (if (null? grouplist) #t ;no more groups to check (and ;check this group (ok?-checkgroup velements (car grouplist)) ;AND/second half: check remaining groups (ok?-checkgroups velements (cdr grouplist)) ) ) )) ;Checks if all finalized elements (non-list and non-zero) ;are legal (aren't duplicates among rows/columns/boxes). ;param elements: a LIST representing the Suduko grid ;returns: #t if all finalized elements are legal. #f otherwise (define ok? (lambda (elements) (ok?-checkgroups (list->vector elements) groups) )) ; Lomax Escarmant ; Programming Language Theory ; 4005-710-01 ; returns a list of those entries in the list elements whose indices ; appear in the list who. (define select (lambda (who elements) (map (lambda (n) (list-ref elements n)) who))) (define rows '#( ; maps position to all positions on it's row ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 0 1 2 3 4 5 6 7 8) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 9 10 11 12 13 14 15 16 17) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 18 19 20 21 22 23 24 25 26) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 27 28 29 30 31 32 33 34 35) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 36 37 38 39 40 41 42 43 44) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 45 46 47 48 49 50 51 52 53) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 54 55 56 57 58 59 60 61 62) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 63 64 65 66 67 68 69 70 71) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) ( 72 73 74 75 76 77 78 79 80) )) (define columns '#( ; maps position to all positions in it's column ( 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) ( 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) ( 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) ( 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) ( 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) ( 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) ( 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) ( 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) ( 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) )) (define boxes '#( ; maps position to all positions in it's box ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 0 1 2 9 10 11 18 19 20) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 3 4 5 12 13 14 21 22 23) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 6 7 8 15 16 17 24 25 26) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 27 28 29 36 37 38 45 46 47) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 30 31 32 39 40 41 48 49 50) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 33 34 35 42 43 44 51 52 53) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 54 55 56 63 64 65 72 73 74) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 57 58 59 66 67 68 75 76 77) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) ( 60 61 62 69 70 71 78 79 80) )) (define groups '( ; list of lists of positions in each row/column/box ; rows ( 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) ; columns ( 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) ; boxes ( 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) )) (define prune (lambda (head candidates tail) (let each ((c candidates) (fit '())) (if (null? c) fit (if (ok? (append head (cons (car c) tail))) (each (cdr c) (cons (car c) fit)) (each (cdr c) fit) ))))) ;checks a list for a digit ;done by josh harlow ;for suduko probelm (define check-list (lambda (list-in digit) (cond ((null? list-in) #f) (else (if (equal? #f (list? list-in)) ; incoming list is only one digit #f (if (equal? (car list-in) digit) #t (check-list (cdr list-in) digit))))))) ;see's how many times the number is repeating (define num-times-repeating (lambda (digit group start-num) (if (null? group) start-num (let ((found-in-own-list (check-list (car group) digit))) (if (equal? #t found-in-own-list) (num-times-repeating digit (cdr group) (+ 1 start-num)) (num-times-repeating digit (cdr group) start-num)))))) ;locates the first position where it occurs ;used only when num-times-repeating returns 1 (define find-group-num (lambda (digit group start-num) (cond ( (null? group) #f) ( else ( if (equal? #t (check-list (car group) digit)) start-num (find-group-num digit (cdr group) (+ start-num 1))))))) ;activator (define unique-slot (lambda (digit group) (let (( num-times (num-times-repeating digit group 0))) (cond ( (equal? 0 num-times) #f) ( (equal? 1 num-times) (find-group-num digit group 0)) (else #f))))) ;Mike Mertsock, PLT 20051 ;Attempts to find a unique final location to place one ;digit within the group of grid locations. ;param group: A list Suduko grid entries. ; example: '(1 (2 3) 5 0 (4 2 6) 7 0 0 8) ;returns: if successful, returns a list with two elements. ;First element is the digit for which we found a location, and ;the second element is the index into the specified group at ;which to place the digit. Returns #f if this attempt fails. ; example: returns '(3 1) for the group above (place 3 at index 1). (define unique-digit-slot (lambda (group) ;for each digit 1 thru 9, try to find unique-slot. ;if found, return immediately, else try n+1 (let loop ((n 1)) (if (> n 9) #f (let ((result (unique-slot n group))) (if (number? result) (list n result) (loop (+ n 1)) ) ) )) )) ; Brian Alliet ; Programming Language Theory ; 4005-710-01 ; Copyright 2005 Brian Alliet ; Sudoku stuff for Homework 2 (define (substitute r n xs) (if (null? xs) '() (if (= 0 n) (cons r (cdr xs)) (cons (car xs) (substitute r (- n 1) (cdr xs)))))) (define undecided (lambda (elements) (let index ((e elements) (idx 0)) (if (null? e) #f (if (list? (car e)) idx (index (cdr e) (+ 1 idx)) ))))) ; Lomax Escarmant ; Programming Language Theory. ; First applies reduce and then tries to substitute for ; unique-digit-slot in each row, coloumn, and box. If the puzzle cannot ; be solved this will return false. (define simplify (lambda (elements) (simplify-rec groups (reduce elements)))) ; Recurses until all rows, columns and boxes are checked (define simplify-rec (lambda (grps elements) (if (null? grps) ; All rows, columns and boxes traversed. elements ;(if (undecided elements) ; Still undecided terms, puzzle not solved. ;#f ;elements ; <-- should be false, view for testing purposes ; Puzzle solved. ;elements) ; There are more rows, columns and boxes to traverse ; Recurse on rows, columns and boxes ((lambda (sub) (if sub ; Found unique digit slot so substitute and start from ; beginning. (simplify (apply substitute (list (car sub) (list-ref (car grps) (cadr sub)) elements))) ; Did not find unique digit slot ; continue in hopes next row, col or box ; will work. (simplify-rec (cdr grps) elements))) ; Attempt to find unique digit slot and pass ; results to preceding lambda (unique-digit-slot (select (car grps) elements)))))) (define f '( 0 0 0 1 0 0 7 0 2 0 3 0 9 5 0 0 0 0 0 0 1 0 0 2 0 0 3 5 9 0 0 0 0 3 0 1 0 2 0 0 0 0 0 7 0 7 0 3 0 0 0 0 9 8 8 0 0 2 0 0 1 0 0 0 0 0 0 8 5 0 6 0 6 0 5 0 0 9 0 0 0 )) (define t '( ; tough 8 3 0 0 0 0 0 4 6 0 2 0 1 0 4 0 3 0 0 0 0 0 0 0 0 0 0 0 0 2 9 0 6 5 0 0 1 4 0 0 0 0 0 2 3 0 0 5 4 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 6 0 3 0 8 0 7 0 9 5 0 0 0 0 0 6 2 )) (define d '( ; diabolical 8 0 0 7 0 1 0 0 2 0 0 6 0 0 0 7 0 0 0 1 7 0 0 0 8 9 0 0 0 0 1 7 3 0 0 0 7 0 0 0 0 0 0 0 6 0 0 0 9 5 6 0 0 0 0 9 5 0 0 0 4 1 0 0 0 8 0 0 0 5 0 0 3 0 0 6 0 5 0 0 7 )) (define hard '( 0 0 0 8 0 2 0 0 0 5 0 0 0 0 0 0 0 1 0 0 6 0 5 0 3 0 0 0 0 9 0 1 0 8 0 0 1 0 0 0 0 0 0 0 2 0 0 0 9 0 7 0 0 0 0 6 1 0 3 0 7 8 0 0 5 0 0 0 0 0 4 0 0 7 2 0 4 0 1 5 0 )) (define hard2 '( 3 0 0 2 0 0 9 0 0 0 0 0 0 0 0 0 0 5 0 7 0 1 0 4 0 0 0 0 0 9 0 0 0 8 0 0 5 0 0 0 7 0 0 0 6 0 0 1 0 0 0 2 0 0 0 0 0 3 0 9 0 4 0 8 0 0 0 0 0 0 0 0 0 0 6 0 0 5 0 0 7 ))