# Sudoku Solver in R

Coming off of the wild excursion of getting Python markdown through RStudio’s knitr (which didnt really work out well… I just exported a Jupyter Lab markdown and arranged it through my Hugo build), this is a brief vantage of how we might write the sudoku puzzle solver in the R language. Here we go.

Using the basic sudoku puzzle from wikipedia HERE, we’ll start to build this out.

Using the same input methods as the python version (here)

Lets bring in the actual board…

```
board <- c(5,3,0,0,7,0,0,0,0,
6,0,0,1,9,5,0,0,0,
0,9,8,0,0,0,0,6,0,
8,0,0,0,6,0,0,0,3,
4,0,0,8,0,3,0,0,1,
7,0,0,0,2,0,0,0,6,
0,6,0,0,0,0,2,8,0,
0,0,0,4,1,9,0,0,5,
0,0,0,0,8,0,0,7,9)
```

First, it’s important to push this into a matrix.

`board <- matrix(board, nrow = 9, ncol = 9, byrow = TRUE) `

Next, lets develop the code to render each cell’s possible answers:

```
possible <- function(board, i, j){
# Creates an all TRUE logical vector
possible <- rep(TRUE,9)
# Lists all known numbers from the row, column, and 3x3 cell
selected_num <- unique(c(board[i,], board[,j], board[3*((i-1) %/% 3) + 1:3, 3*((j-1) %/% 3) + 1:3]))
# Removes NAs
selected_num <- na.omit(selected_num)
# Changes the logical vector to FALSE for all values currently in use for the row, column, and 3x3 cell
possible[selected_num] <- FALSE
# Returns this logical vector for use in subsequent functions...
return(possible)
}
```

As the comments imply, we are simply returning a logical vector list that describes which numbers are available or `possible`

.

Next, we’ll draft the function to iterate through all cells and determine a solution through recursion.

```
# The 'board' argument here provides the matrix, length 81 (9x9), to iterate through.
# The 'progress' argument here provides a starting value to recursively iterate through.
solve <- function(board, progress = 81) {
# Provision to make a matrix with 0s into NA for future processing
if (0 %in% board) {
board[board == 0] <- NA
} else board
# Once all cells have been assessed within the 'possible_choices' function, it stops the recursion.
if (progress == 0) {
# Successfully filled in the board
return(board)
}
# Get the i,j coordinates
# A fancy way to iterate through the coordinate numbers one by one (right to left, bottom to top)
i <- ((progress - 1) %% 9) + 1
j <- ((progress - 1) %/% 9) + 1
# If a spot is open, identifies what numbers are available `choices`
if (is.na(board[i, j])) {
choices <- which(possible(board, i, j))
} else{
choices <- c(board[i, j])
}
# Try each possible choice, until all the requirements of the two functions are satisfied.
for (k in choices) {
board[i, j] <- k
# recursion
answer <- solve(board, progress - 1)
# If all possible positions have been completed, simply return the answer.
if (!is.null(answer)) {
return(answer)
}
}
return(NULL)
}
```

Although there is a lot going on here, I’ve attempted to put in some fairly descriptive comments. I tried to follow the Python code thematic plan, while using some of R’s fantastic infix operators to skip a few steps here or there and a bit of recursion. You’ll also note that I also switch all zeros to NAs, to make things a bit easier to code using `is.na`

.

`solve(board)`

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

Arguably, I’m not a base R coder or programmer. Therefore, much of this post was generated from various websites, SOF, and other corners of the web–the R community is amazing. In a future post, I’ll work to re-write this in some type of tidyverse rendition… if that is a thing. I’ll at least try.