samedi 26 décembre 2020

Python: What is the difference between these two loops comparing and removing numbers from their lists?

I decided to write a code generating a 9x9 array with sudoku rules(digits 1-9 never repeating in rows, columns, or specific 3x3 boxes). I ran into a problem where my for loop chained with an if statement to remove numbers not in a list from a different list would not remove all the numbers needed. Here is the code for the loops:

#Option1, I have found to be successful
Avail = [item3 for item3 in Avail if item3 not in sameboxrows]
   #line 98 in my full code
#Option2, would miss some of the numbers in the list
for item3 in Avail:
    if item3 in sameboxrows:
        Avail.remove(item3)
   #line 99 in my full code

There are also 2 more loops like this in the full code

Option1 with some added code printed this out for me:

#Avail = list of numbers available by row and collumn
#*samebox = list of numbers already in the 3x3 box (to be removed from Avail)
#*Avail = list of numbers available by row collumn and box (should not include numbers from *samebox)

Avail    [1, 2, 3, 5]
*samebox [7, 4, 1, 9, 6, 5]
*Avail   [2, 3]

Option2 with the same code printed this out for me:

#Avail = list of numbers available by row and collumn
#*samebox = list of numbers already in the 3x3 box (to be removed from Avail)
#*Avail = list of numbers available by row collumn and box (should not include numbers from *samebox)

Avail    [1, 3, 4, 5, 6, 9]
*samebox [4, 2, 6, 1, 7, 3]
*Avail   [3, 5, 9]

Above, the numbers 1 4 6 were removed but not 3

Here is my full code incase you need more details:

import random
grid = []
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])
grid.append([0,0,0,0,0,0,0,0,0])


def SudokuFinal(grid):
    for row in range(len(grid)):
        #initializing after ever row
        rowavail = [1,2,3,4,5,6,7,8,9]
        sum = 3
        RBTR = grid[row-1][-3:]
        for col in range(len(grid)):
            colavail = [1,2,3,4,5,6,7,8,9]
            rowabove = grid[row-1]
            Avail = rowavail[:]
            print()
            print(row,col)
            print()
            print('Avail   ',Avail)
            print('row     ',rowavail)
            print('collumn ',colavail)
            print('rowabove',rowabove)
            print('RBTR    ',RBTR)             
            print()
            
            #collumnstart
            #print('collumn ',colavail)
            print('Avail   ',Avail)
            for chkrow in range(len(grid)):
                if grid[chkrow][col] in colavail:
                    colavail.remove(grid[chkrow][col])
            print('*collumn',colavail)
            
            #comparing lists and editing final availablilities
            Avail = [item1 for item1 in Avail if item1 in colavail]
            #for item1 in Avail:
                #if item1 not in colavail:
                    #Avail.remove(item1)
                    
            print('*Avail ',Avail)
            print()
            #collumn ^
            
            
            
            #box start
            #print('rowabove',rowabove)
            print('Avail   ',Avail)
            #rows 1 4 7 only need collumn restrictions, i think ???
            #rows 2 5 8
            if row%3==1:
                #col 1 2 3
                if col//3==0:
                    rowabove=rowabove[3:]
                    print("*owabove",rowabove)
                #col 4 5 6
                elif col//3==1:
                    rowabove=rowabove[:3]+rowabove[6:]
                    print("*owabove",rowabove)
                #col 7 8 9
                else:
                    rowabove=rowabove[:6]
                    print("*owabove",rowabove)
                
                #comparing lists and editing final availablilities
                Avail = [item2 for item2 in Avail if item2 in rowabove]
                #for item2 in Avail:
                    #if item2 not in rowabove:
                        #Avail.remove(item2)
                
                print('*Avail ',Avail)
                print()
                
                
            #rows 3 6 9
            elif row%3==2:
                #col 1 2 3
                if col//3==0:
                    sameboxrows = grid[row-1][:3]+grid[row-2][:3]
                    print("*samebox",sameboxrows)
                #col 4 5 6
                elif col//3==1:
                    sameboxrows = grid[row-1][3:6]+grid[row-2][3:6]
                    print("*samebox",sameboxrows)
                if col//3==2:
                    sameboxrows = grid[row-1][6:]+grid[row-2][6:]
                    print("*samebox",sameboxrows)
                
                #comparing lists and editing final availablilities
                Avail = [item3 for item3 in Avail if item3 not in sameboxrows]
                #for item3 in Avail:
                    #if item3 in sameboxrows:
                        #Avail.remove(item3)
                
                print('*Avail ',Avail)
                print()
            #box ^
            
            
            
            print("RBTR",RBTR)
            print ()
            
            if sum == col and col//3==1 and row%3==1:
                dig = random.choice(RBTR)
            else:
                dig = random.choice(Avail)
            print("dig",dig)
            print()
            print("sum",sum)
            rowavail.remove(dig)            
            grid[row][col]=dig
            
            if dig in RBTR:
                sum += 1
                RBTR.remove(dig)
            
            print()
            print('AVAIL   ',Avail)
            print('ROW     ',rowavail)
            print('COLLUMN ',colavail)
            print()
            
            
            for row2 in grid:
                print (row2)
            print()
            print()
            print()            
    print(grid)
    return (grid)    

#def SudokuSolve():
    

SudokuFinal(grid)

My final Questions:

What is the difference between for loops Option1 and Ooption2?

Is there some of my code that can be done with way better efficiency?

Any other helpful tips?

-

Additional Comments:

My code is not finished and it stops with errors. I used my RBTR variable to ensure the Right boxes, second rows had numbers left over to use. I need to do the same but vertical, probably within my #collumnstart/chkrow loop.

RBTR means 'Right Box Top Row', and sum relates directly to RBTR.

I already found a 40 line code that will do what I want but I'd like to do something on my own first.

I'm also thinking about redoing it all. Right now I have each digit assignment going row by row. I'm thinking goin diagonally from 0,0 will be easier with the RBTR/sum combo and the RBTR I want to do vertically.

This is my first question on Stack Overflow so maybe I'll give an update later, I don't know.

Aucun commentaire:

Enregistrer un commentaire