Omid - Challenge 19

data-challenges
advanced-exercises
🔰 Question Result X Challenge 19: Suduku in Excel Solve the left side Suduku table and replace X by number based on the below rule: Use the numbers 1 through 6 instead of…
Published

March 24, 2026

Illustration for Omid - Challenge 19

Challenge Description

🔰 Question Result X Challenge 19: Suduku in Excel Solve the left side Suduku table and replace X by number based on the below rule: Use the numbers 1 through 6 instead of…

Solutions

library(tidyverse)
library(readxl)

input = read_excel("files/CH-019 Suduku in Excel.xlsx", range = "B3:G8",
                   col_names = FALSE) %>% 
  mutate_all(as.numeric)
test  = read_excel("files/CH-019 Suduku in Excel.xlsx", range = "O3:T8",
                   col_names = FALSE) 

row_na = apply(input, 1, function(x) sum(is.na(x)))
row_na = which(row_na == 1)
for (r in 1:length(row_na)) {
  input[row_na[r], which(is.na(input[row_na[r],]))] = 21 - sum(input[row_na[r],], na.rm = TRUE)
}
col_na = apply(input, 2, function(x) sum(is.na(x)))
col_na = which(col_na == 1)
for (c in 1:length(col_na)) {
  input[which(is.na(input[,col_na[c]])), col_na[c]] = 21 - sum(input[,col_na[c]], na.rm = TRUE)
}
row_na = apply(input, 1, function(x) sum(is.na(x)))
row_na = which(row_na == 1)
for (r in 1:length(row_na)) {
  input[row_na[r], which(is.na(input[row_na[r],]))] = 21 - sum(input[row_na[r],], na.rm = TRUE)
}
col_na = apply(input, 2, function(x) sum(is.na(x)))
col_na = which(col_na == 1)
for (c in 1:length(col_na)) {
  input[which(is.na(input[,col_na[c]])), col_na[c]] = 21 - sum(input[,col_na[c]], na.rm = TRUE)
}

missing = which(is.na(input), arr.ind = TRUE)
col_of_missing = missing[,2] %>% unique()
row_of_missing = missing[,1] %>% unique()

first_row = setdiff(1:6, input[row_of_missing[1],])
second_row = setdiff(1:6, input[row_of_missing[2],]) 

first_col = input[, col_of_missing[1]] %>% na.omit() %>% pull() %>% setdiff(1:6,.)
second_col = input[, col_of_missing[2]] %>% na.omit() %>% pull() %>% setdiff(1:6,.)

input[row_of_missing[1], col_of_missing[1]] <- intersect(first_row, first_col) 
input[row_of_missing[2], col_of_missing[2]] <- intersect(second_row, second_col)

row_na = apply(input, 1, function(x) sum(is.na(x)))
row_na = which(row_na == 1)
for (r in 1:length(row_na)) {
  input[row_na[r], which(is.na(input[row_na[r],]))] = 21 - sum(input[row_na[r],], na.rm = TRUE)
}

identical(input, test)
# [1] TRUE
  • Logic:

    • Reads the workbook ranges needed for the challenge

    • Builds the intermediate columns that drive the final result

    • Applies the rule iteratively until the output stabilizes

  • Strengths:

    • The R solution stays close to the workbook rule and keeps the transformation compact.
  • Areas for Improvement:

    • The code assumes the sheet structure and source ranges remain stable.
  • Gem:

    • The strongest part of the solution is choosing the right intermediate representation before shaping the final output.
import numpy as np
import pandas as pd

input_data = pd.read_excel("CH-019 Suduku in Excel.xlsx", usecols="B:G", skiprows=2, nrows=6, header=None).apply(pd.to_numeric)
test = pd.read_excel("CH-019 Suduku in Excel.xlsx", usecols="O:T", skiprows=2, nrows=6, header=None)

grid = input_data.to_numpy(dtype=float)

def fill_single_missing_rows_cols(arr):
    changed = True
    while changed:
        changed = False
        for i in range(arr.shape[0]):
            mask = np.isnan(arr[i])
            if mask.sum() == 1:
                arr[i, np.where(mask)[0][0]] = 21 - np.nansum(arr[i])
                changed = True
        for j in range(arr.shape[1]):
            mask = np.isnan(arr[:, j])
            if mask.sum() == 1:
                arr[np.where(mask)[0][0], j] = 21 - np.nansum(arr[:, j])
                changed = True
    return arr

grid = fill_single_missing_rows_cols(grid)
missing = np.argwhere(np.isnan(grid))
if len(missing) == 2:
    rows = np.unique(missing[:, 0])
    cols = np.unique(missing[:, 1])
    first_row = set(range(1, 7)) - set(grid[rows[0], ~np.isnan(grid[rows[0]])].astype(int))
    second_row = set(range(1, 7)) - set(grid[rows[1], ~np.isnan(grid[rows[1]])].astype(int))
    first_col = set(range(1, 7)) - set(grid[~np.isnan(grid[:, cols[0]]), cols[0]].astype(int))
    second_col = set(range(1, 7)) - set(grid[~np.isnan(grid[:, cols[1]]), cols[1]].astype(int))
    grid[rows[0], cols[0]] = list(first_row & first_col)[0]
    grid[rows[1], cols[1]] = list(second_row & second_col)[0]
grid = fill_single_missing_rows_cols(grid)

print(np.array_equal(grid, test.to_numpy()))
  • Logic:

    • Reads the workbook ranges needed for the challenge

    • Applies the rule iteratively until the output stabilizes

  • Strengths:

    • The Python version follows the same rule in a direct dataframe-oriented implementation.
  • Areas for Improvement:

    • The code assumes the workbook layout remains stable, so any sheet redesign would require small adjustments.
  • Gem:

    • The implementation stays close to the original workbook rule instead of adding unnecessary abstraction.

Difficulty Level

This task is moderate:

  • The business rule is readable, but the workbook still requires careful implementation to reach the expected layout.