cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
413
Views
1
Helpful
0
Replies

Fun Friday: From Programming to Commanding

yawming
Cisco Employee
Cisco Employee

The new way to code is here.

yawming_0-1691095306903.png

Sudoku is a popular puzzle game. The objective is to fill a 9x9 square grid, divided into smaller 3x3 boxes, with digits so that each column, each row, and each of the nine 3x3 blocks that compose the grid contain all of the digits from 1 to 9.

How do you generate these numbers with Python? I believe you can figure out the algorithm to randomly generate these numbers, but it won't be straight forward. I'm curious about how to write Python code to create a Sudoku puzzle.

In the past, I would figure out the logic and then start coding. It probably would have taken me a while to figure out the logic, program, and test the code. But amazingly, nowadays it takes me less than a minute to command the code.

I started asking ChatGPT for the code, and in just a matter of seconds, I got the code. The code is surprisingly short; I have to admit, it's hard for me to read. So, I asked for comments. With the comments, it's much easier to read. Here is the code:

 

 

# Import the random module for shuffling
import random

# Define the function to generate a 9x9 minidoku (sudoku) grid
def generate_minidoku():
    
    # Define the base and side lengths for the grid
    base  = 3
    side  = base*base
    
    # Generate a list of numbers from 1 to 9
    nums  = list(range(1, base*base + 1))

    # Define the pattern function which helps to decide where numbers will go in the grid
    def pattern(r,c): return (base*(r%base)+r//base+c)%side
    
    # Define a shuffle function for randomizing the order of elements in a list
    def shuffle(s): return random.sample(s,len(s)) 

    # Generate shuffled sequences for rows and columns
    rBase = range(base)
    rows  = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ] 
    cols  = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
    
    # Shuffle the sequence of numbers
    nums  = shuffle(nums)

    # Use the shuffled rows, columns, and numbers to generate a 9x9 grid
    grid = [ [nums[pattern(r,c)] for c in cols] for r in rows ]

    # Print the generated grid
    for line in grid: print(line)

# Call the function to generate a minidoku
generate_minidoku()

 

 

And this is the output:

 

 

[7, 3, 6, 2, 5, 8, 9, 1, 4]
[5, 2, 8, 9, 1, 4, 3, 7, 6]
[1, 9, 4, 3, 7, 6, 2, 5, 8]
[4, 7, 3, 5, 6, 2, 1, 8, 9]
[6, 5, 2, 1, 8, 9, 7, 4, 3]
[8, 1, 9, 7, 4, 3, 5, 6, 2]
[3, 6, 5, 8, 2, 1, 4, 9, 7]
[2, 8, 1, 4, 9, 7, 6, 3, 5]
[9, 4, 7, 6, 3, 5, 8, 2, 1]

 

 

It seems to be working. However, my request may not have been detailed enough; it generates a fully completed Sudoku grid, not a playable Sudoku puzzle with some empty cells. Therefore, I asked again for a version that removes some numbers to make it playable, and I received the following code:

 

 

import random

def generate_minidoku(holes=10):
    # Define the base of the sudoku, and calculate the side (number of rows/columns)
    base  = 3
    side  = base*base
    
    # Create a list of numbers from 1 to side (inclusive)
    nums  = list(range(1, base*base + 1))

    # Define a pattern function for the placement of numbers in the grid
    def pattern(r,c): return (base*(r%base)+r//base+c)%side
    
    # Define a function to shuffle a given list
    def shuffle(s): return random.sample(s,len(s)) 

    # Generate a range from 0 to base (exclusive)
    rBase = range(base)
    
    # Shuffle the rows and columns
    rows  = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ] 
    cols  = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
    
    # Shuffle the numbers
    nums  = shuffle(nums)

    # Generate the Sudoku grid by placing the shuffled numbers in a shuffled pattern
    grid = [ [nums[pattern(r,c)] for c in cols] for r in rows ]

    # Calculate the total number of squares in the grid
    squares = side*side
    empties = holes
    
    # Randomly select some squares to be emptied (value set to 0)
    for p in random.sample(range(squares),empties):
        grid[p//side][p%side] = 0

    # Print each line of the grid
    for line in grid: print(line)

# Generate a Sudoku with 30 empty squares
generate_minidoku(30)

 

 

Here is the output. '0' represents the unknown numbers that the player needs to replace with the correct ones.

 

 

[1, 9, 6, 3, 0, 0, 7, 4, 8]
[0, 0, 2, 4, 8, 7, 9, 0, 0]
[4, 0, 8, 1, 6, 9, 0, 3, 0]
[6, 3, 0, 0, 0, 4, 0, 8, 9]
[0, 0, 0, 8, 9, 1, 0, 0, 5]
[8, 1, 9, 6, 5, 3, 0, 2, 0]
[9, 6, 3, 5, 0, 2, 0, 0, 1]
[5, 2, 4, 7, 0, 0, 6, 9, 3]
[7, 0, 0, 9, 0, 6, 0, 0, 4]

 

 

It's better, but there are still issues. It's not playable as it stands because we need to remove the '0's and enter the correct numbers. Additionally, there are no 3x3 grid boxes. The conversation with ChatGPT is in the same thread, and it seems like it finally understood my intention when I asked to remove the '0's, leave them blank, and draw # shaped grid lines to create 3x3 blocks.
Here is the final codes:

 

 

import random

# Function to generate a Sudoku puzzle with a given number of holes.
def generate_minidoku(holes=20):
    base  = 3
    side  = base*base
    nums  = list(range(1, base*base + 1))  # list of numbers 1 to 9.

    # Function to generate a pattern of numbers.
    def pattern(r,c): return (base*(r%base)+r//base+c)%side

    # Function to shuffle the elements of a list.
    def shuffle(s): return random.sample(s,len(s)) 

    rBase = range(base)
    # Shuffling the rows.
    rows  = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ] 
    # Shuffling the columns.
    cols  = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
    # Shuffling the numbers.
    nums  = shuffle(nums)

    # Generating the grid using the pattern.
    grid = [ [nums[pattern(r,c)] for c in cols] for r in rows ]

    squares = side*side
    empties = holes
    # Randomly emptying the specified number of cells.
    for p in random.sample(range(squares),empties):
        grid[p//side][p%side] = 0

    return grid

# Function to print the Sudoku puzzle.
def print_grid(grid):
    for i in range(len(grid)):
        for j in range(len(grid[i])):
            # Printing vertical lines every 3 numbers.
            if j % 3 == 0 and j != 0:  
                print(" |", end='')
            # Printing a blank space for zeros.
            if grid[i][j] == 0:   
                print("  ", end='')
            else:
                print(" " + str(grid[i][j]), end='')
        # Printing horizontal lines every 3 numbers.
        if (i+1) % 3 == 0 and i != len(grid) - 1:  
            print("\n" + '-' * 23)
        else:
            print()

# Generating a Sudoku puzzle with 30 holes.
grid = generate_minidoku(30)
# Printing the generated puzzle.
print_grid(grid)

 

 

And the output:

 

 

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

 

 

From the initial request to the final one, it took less than 10 minutes. Will AI tools someday become indispensable assistants in programming?  Try asking ChatGPT something like, 'Cisco DNAC API authentication python script', and see if it can surprise you.

 

 

 

0 Replies 0