1

My partner in a summative for HS gave me this algorithm, I was hoping somebody could tell me if there is a more eloquent way of coding this.. CB is current board position(global), its a list of lists.

for a in xrange(0, 3): 
  for b in xrange(0, 3):
    for j in xrange(1, 4): 
      for k in xrange(1, 4): 
        boxsum += CB[3a + j][3b + k] 
        if not(boxsum == 45):        
          return False               
        boxsum = 0
  • I am a casual sudoku player. What is "the 3x3"? – MxLDevs Jun 03 '14 at 13:57
  • I think he means "the constraint that a 3x3 box must contain every number from 1 to 9". – Kevin Jun 03 '14 at 13:58
  • Before looking for a more elegant solution, it may be a useful starting point to verify that what you've already got works. I see some problems: `boxsum` isn't defined when you first add to it, `3a` and `3b` isn't valid syntax, and the last three lines appear to be improperly indented. (and the `if` would probably look better as `if boxsum != 45:`, but that's a matter of opinion) – Kevin Jun 03 '14 at 14:05
  • [An obligatory sudoku link](http://norvig.com/sudoku.html) – georg Jun 03 '14 at 14:06

4 Answers4

1

First, the following code is not indented correctly:

if not(boxsum == 45):        
    return False               
boxsum = 0

(with the current indentation it will always fail on the first time this code is executed)

Second, in the following line:

boxsum += CB[3a + j][3b + k] 

you probably meant to do:

boxsum += CB[3*a + j][3*b + k] 

And last, in order to check a 3x3 part of sudoku game it is not enough to check the sum - you should also check that every number between 1-9 is present (or in other words, that all the numbers are in the range 1-9 and there is no number that appears more than once).

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
0

There are dozens of "cleaner" ways to do so.

First of all, why not use numpy for matrices, where you are obviously working with a matrix? I am assuming your numeration (which is a bit odd, why you start numerating from "1"?)

import numpy as np
CB = np.array(CB)

def constraint3x3check(CB):
    return np.all(np.sum( CB[3*a+1:3*a+3, 3*b+1:3*b+3)==45 for a in range(3) for b in range(3))
lejlot
  • 64,777
  • 8
  • 131
  • 164
0

Given the sum of the box equals 45, that doesn't mean there are all 1-9 numbers present.

You could for example add your numbers to set and check if the length of the set is always 9.

pacholik
  • 8,607
  • 9
  • 43
  • 55
0

Since the sum 45 does not mean the answer is correct, necessarily, a different way is needed. Personally, I would join the rows into a single list and compare them to the list (1,2,...9), e.g.

#assuming this is your format...
box = [[4,2,3],[1,5,9],[8,7,6]]

def valid_box(box):
    check_list = []
    for row in box:
        check_list += row
    return list(range(1,10)) == sorted(check_list)

Although the code creating the list could also be done with list comprehension (I have no idea which one is more efficient, processor-wise)

def valid_box2(box):
    return list(range(1,10)) == sorted( [item for row in box for item in row ] )

Merge list code taken from Making a flat list out of list of lists in Python

Community
  • 1
  • 1
pseudonym117
  • 799
  • 1
  • 5
  • 22