Open In App

Solve the Crossword Puzzle

Improve
Improve
Like Article
Like
Save
Share
Report

A 10 x 10 Crossword grid is provided, along with a set of words (or names of places) which need to be filled into the grid. The cells in the grid are initially, either + signs or signs. Cells marked with a ‘+’ have to be left as they are. Cells marked with a ‘-‘ need to be filled up with an appropriate character. You are also given an array of words that need to be filled in Crossword grid.

Example :

Input :
+++++++++-
-++++++++-
-------++-
-++++++++-
-++++++++-
-++++-----
------+++-
-++++++++-
+---------
++++++++++

Output :
+++++++++C
P++++++++H
HISTORY++E
Y++++++++M
S++++++++I
I++++MATHS
CIVICS+++T
S++++++++R
+GEOGRAPHY
++++++++++

The approach behind this is to recursively check for each word in the vertical position and in the horizontal position. Then fill the word in the matrix that can be the best fit in the corresponding position of the grid, then update the crossword grid by filling the gap with that word. 

Implementation:

C++




// CPP code to fill the crossword puzzle
#include <bits/stdc++.h>
using namespace std;
 
// ways are to calculate the number of
// possible ways to fill the grid
int ways = 0;
 
// this function is used to print
// the resultant matrix
void printMatrix(vector<string>& matrix, int n)
{
    for (int i = 0; i < n; i++)
        cout << matrix[i] << endl;
}
 
// this function checks for the current word
// if it can be placed horizontally or not
// x -> it represent index of row
// y -> it represent index of column
// currentWord -> it represent the
// current word in word array
vector<string> checkHorizontal(int x, int y,
                            vector<string> matrix,
                            string currentWord)
{
    int n = currentWord.length();
 
    for (int i = 0; i < n; i++) {
        if (matrix[x][y + i] == '#' ||
            matrix[x][y + i] == currentWord[i]) {
            matrix[x][y + i] = currentWord[i];
        }
        else {
 
            // this shows that word cannot
            // be placed horizontally
            matrix[0][0] = '@';
            return matrix;
        }
    }
 
    return matrix;
}
 
// this function checks for the current word
// if it can be placed vertically or not
// x -> it represent index of row
// y -> it represent index of column
// currentWord -> it represent the
// current word in word array
vector<string> checkVertical(int x, int y,
                            vector<string> matrix,
                            string currentWord)
{
    int n = currentWord.length();
 
    for (int i = 0; i < n; i++) {
        if (matrix[x + i][y] == '#' ||
            matrix[x + i][y] == currentWord[i]) {
            matrix[x + i][y] = currentWord[i];
        }
        else {
 
            // this shows that word
            // cannot be placed vertically
            matrix[0][0] = '@';
            return matrix;
        }
    }
    return matrix;
}
 
// this function recursively checks for every
// word that can align vertically in one loop
// and in another loop it checks for those words
// that can align horizontally words -> it
// contains all the words to fill in a crossword
// puzzle matrix -> it contain the current
// state of crossword index -> it represent
// the index of current word n -> it represent
// the length of row or column of the square matrix
void solvePuzzle(vector<string>& words,
                vector<string> matrix,
                int index, int n)
{
    if (index < words.size()) {
        string currentWord = words[index];
        int maxLen = n - currentWord.length();
 
        // loop to check the words that can align vertically.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= maxLen; j++) {
                vector<string> temp = checkVertical(j, i,
                                        matrix, currentWord);
 
                if (temp[0][0] != '@') {
                    solvePuzzle(words, temp, index + 1, n);
                }
            }
        }
 
        // loop to check the words that can align horizontally.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= maxLen; j++) {
                vector<string> temp = checkHorizontal(i, j,
                                    matrix, currentWord);
 
                if (temp[0][0] != '@') {
                    solvePuzzle(words, temp, index + 1, n);
                }
            }
        }
    }
    else {
        // calling of print function to
        // print the crossword puzzle
        cout << (ways + 1) << " way to solve the puzzle "
            << endl;
        printMatrix(matrix, n);
        cout << endl;
 
        // increase the ways
        ways++;
        return;
    }
}
 
// Driver Code
int main()
{
    // length of grid
    int n1 = 10;
 
    // matrix to hold the grid of puzzle
    vector<string> matrix;
 
    // take input of puzzle in matrix
    // input of grid of size n1 x n1
    matrix.push_back("*#********");
    matrix.push_back("*#********");
    matrix.push_back("*#****#***");
    matrix.push_back("*##***##**");
    matrix.push_back("*#****#***");
    matrix.push_back("*#****#***");
    matrix.push_back("*#****#***");
    matrix.push_back("*#*######*");
    matrix.push_back("*#********");
    matrix.push_back("***#######");
 
    vector<string> words;
 
    // the words matrix will hold all
    // the words need to be filled in the grid
    words.push_back("PUNJAB");
    words.push_back("JHARKHAND");
    words.push_back("MIZORAM");
    words.push_back("MUMBAI");
 
    // initialize the number of ways
    // to solve the puzzle to zero
    ways = 0;
 
    // recursive function to solve the puzzle
    // Here 0 is the initial index of words array
    // n1 is length of grid
    solvePuzzle(words, matrix, 0, n1);
    cout << "Number of ways to fill the grid is "
        << ways << endl;
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class Main {
     
    // ways are to calculate the number of
    // possible ways to fill the grid
    static int ways = 0;
     
    // this function is used to print
    // the resultant matrix
    public static void printMatrix(List<String> matrix, int n) {
        for (int i = 0; i < n; i++) {
            System.out.println(matrix.get(i));
        }
    }
     
     
    // this function checks for the current word
    // if it can be placed horizontally or not
    // x -> it represent index of row
    // y -> it represent index of column
    // currentWord -> it represent the
    // current word in word array
    public static List<String> checkHorizontal(int x, int y, List<String> matrix, String currentWord) {
        int n = currentWord.length();
 
        for (int i = 0; i < n; i++) {
            if (matrix.get(x).charAt(y + i) == '#' || matrix.get(x).charAt(y + i) == currentWord.charAt(i)) {
                StringBuilder sb = new StringBuilder(matrix.get(x));
                sb.setCharAt(y + i, currentWord.charAt(i));
                matrix.set(x, sb.toString());
            } else {
                 
                // this shows that word cannot
                // be placed horizontally
                matrix.set(0, "@");
                return matrix;
            }
        }
 
        return matrix;
    }
     
    // this function checks for the current word
    // if it can be placed vertically or not
    // x -> it represent index of row
    // y -> it represent index of column
    // currentWord -> it represent the
    // current word in word array
    public static List<String> checkVertical(int x, int y, List<String> matrix, String currentWord) {
        int n = currentWord.length();
 
        for (int i = 0; i < n; i++) {
            if (matrix.get(x + i).charAt(y) == '#' || matrix.get(x + i).charAt(y) == currentWord.charAt(i)) {
                StringBuilder sb = new StringBuilder(matrix.get(x + i));
                sb.setCharAt(y, currentWord.charAt(i));
                matrix.set(x + i, sb.toString());
            } else {
                 
                 
                // this shows that word
                // cannot be placed vertically
                matrix.set(0, "@");
                return matrix;
            }
        }
 
        return matrix;
    }
     
     
     
    // this function recursively checks for every
    // word that can align vertically in one loop
    // and in another loop it checks for those words
    // that can align horizontally words -> it
    // contains all the words to fill in a crossword
    // puzzle matrix -> it contain the current
    // state of crossword index -> it represent
    // the index of current word n -> it represent
    // the length of row or column of the square matrix
    public static void solvePuzzle(List<String> words, List<String> matrix, int index, int n) {
        if (index < words.size()) {
            String currentWord = words.get(index);
            int maxLen = n - currentWord.length();
             
            // loop to check the words that can align vertically.
            for (int i = 0; i < n; i++) {
                for (int j = 0; j <= maxLen; j++) {
                    List<String> temp = new ArrayList<>(checkVertical(j, i, new ArrayList<>(matrix), currentWord));
 
                    if (!temp.get(0).equals("@")) {
                        solvePuzzle(words, temp, index + 1, n);
                    }
                }
            }
             
            // loop to check the words that can align horizontally.
            for (int i = 0; i < n; i++) {
                for (int j = 0; j <= maxLen; j++) {
                    List<String> temp = new ArrayList<>(checkHorizontal(i, j, new ArrayList<>(matrix), currentWord));
 
                    if (!temp.get(0).equals("@")) {
                        solvePuzzle(words, temp, index + 1, n);
                    }
                }
            }
        } else {
             
            // calling of print function to
            // print the crossword puzzle
            System.out.println((ways + 1) + " way to solve the puzzle ");
            printMatrix(matrix, n);
            System.out.println();
             
            // increase the ways
            ways++;
            return;
        }
    }
     
    // Driver Code
    public static void main(String[] args) {
         
        // length of grid
        int n1 = 10;
         
        // matrix to hold the grid of puzzle
        List<String> matrix = new ArrayList<>();
         
        // take input of puzzle in matrix
        // input of grid of size n1 x n1
        matrix.add("*#********");
        matrix.add("*#********");
        matrix.add("*#****#***");
        matrix.add("*##***##**");
        matrix.add("*#****#***");
        matrix.add("*#****#***");
        matrix.add("*#****#***");
        matrix.add("*#*######*");
        matrix.add("*#********");
        matrix.add("***#######");
 
        List<String> words = new ArrayList<>();
         
         
        // the words matrix will hold all
        // the words need to be filled in the grid
        words.add("PUNJAB");
        words.add("JHARKHAND");
        words.add("MIZORAM");
        words.add("MUMBAI");
         
         
        // initialize the number of ways
        // to solve the puzzle to zero
        ways = 0;
         
         
        // recursive function to solve the puzzle
        // Here 0 is the initial index of words array
        // n1 is length of grid
        solvePuzzle(words, matrix, 0, n1);
        System.out.println("Number of ways to fill the grid is " + ways);
    }
}
 
// This code is contributed by Prince Kumar


Python3




# Python program for the above approach
 
# Ways to calculate the number of
# Possible ways to fill the grid
ways = 0
 
# This function is used to print
# The resultant matrix
def printMatrix(matrix, n):
    for i in range(n):
        print(matrix[i])
 
# This function checks for the current word
# If it can be placed horizontally or not
# x -> it represent index of row
# y -> it represent index of column
# currentWord -> it represent the
# Current word in word array
def checkHorizontal(x, y, matrix, currentWord):
    n = len(currentWord)
 
    for i in range(n):
        if matrix[x][y + i] == '#' or matrix[x][y + i] == currentWord[i]:
            matrix[x] = matrix[x][:y + i] + currentWord[i] + matrix[x][y + i + 1:]
        else:
             
            # This shows that word cannot
            # Be placed horizontally
            matrix[0] = "@"
            return matrix
    return matrix
 
# This function checks for the current word
# If it can be placed vertically or not
# x -> it represent index of row
# y -> it represent index of column
# currentWord -> it represent the
# Current word in word array
def checkVertical(x, y, matrix, currentWord):
    n = len(currentWord)
 
    for i in range(n):
        if matrix[x + i][y] == '#' or matrix[x + i][y] == currentWord[i]:
            matrix[x + i] = matrix[x + i][:y] + currentWord[i] + matrix[x + i][y + 1:]
        else:
             
            # This shows that word
            # Cannot be placed vertically
            matrix[0] = "@"
            return matrix
    return matrix
 
# This function recursively checks for every
# Word that can align vertically in one loop
# And in another loop it checks for those words
# That can align horizontally words -> it
# Contains all the words to fill in a crossword
# Puzzle matrix -> it contain the current
# State of crossword index -> it represent
# The index of current word n -> it represent
# The length of row or column of the square matrix
def solvePuzzle(words, matrix, index, n):
    global ways
    if index < len(words):
        currentWord = words[index]
        maxLen = n - len(currentWord)
         
        # Loop to check the words that can align vertically.
        for i in range(n):
            for j in range(maxLen + 1):
                temp = checkVertical(j, i, matrix.copy(), currentWord)
                if temp[0] != "@":
                    solvePuzzle(words, temp, index + 1, n)
         
        # Loop to check the words that can align horizontally.
        for i in range(n):
            for j in range(maxLen + 1):
                temp = checkHorizontal(i, j, matrix.copy(), currentWord)
                if temp[0] != "@":
                    solvePuzzle(words, temp, index + 1, n)
    else:
         
        # Calling of print function to
        # Print the crossword puzzle
        print(str(ways + 1) + " way to solve the puzzle ")
        printMatrix(matrix, n)
        print()
         
        # Increase the ways
        ways += 1
        return
 
# Driver Code
if __name__ == '__main__':
    # Length of grid
    n1 = 10
     
    # Matrix to hold the grid of puzzle
    matrix = []
     
    # Take input of puzzle in matrix
    # Input of grid of size n1 x n1
    matrix.append("*#********")
    matrix.append("*#********")
    matrix.append("*#****#***")
    matrix.append("*##***##**")
    matrix.append("*#****#***")
    matrix.append("*#****#***")
    matrix.append("*#****#***")
    matrix.append("*#*######*")
    matrix.append("*#********")
    matrix.append("***#######")
 
    words = []
     
    # The words matrix will hold all
    # The words need to be filled in the grid
    words.append("PUNJAB")
    words.append("JHARKHAND")
    words.append("MIZORAM")
    words.append("MUMBAI")
     
     
    # Initialize the number of ways
    # To solve the puzzle to zero
    ways = 0
     
     
    # Recursive function to solve the puzzle
    # Here 0 is the initial index of words array
    # n1 is length of grid
    solvePuzzle(words, matrix, 0, n1)
    print("Number of ways to fill the grid is " + str(ways))


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Number of ways to fill the grid
    static int ways = 0;
 
    // Function to print the crossword puzzle
    static void PrintMatrix(List<string> matrix)
    {
        foreach (string row in matrix)
        {
            Console.WriteLine(row);
        }
    }
 
    // Function to check if the current word can be placed horizontally
    static List<string> CheckHorizontal(int x, int y, List<string> matrix, string currentWord)
    {
        int n = currentWord.Length;
 
        for (int i = 0; i < n; i++)
        {
            if (matrix[x][y + i] == '#' || matrix[x][y + i] == currentWord[i])
            {
                matrix[x] = matrix[x].Remove(y + i, 1).Insert(y + i, currentWord[i].ToString());
            }
            else
            {
                // Word cannot be placed horizontally
                matrix[0] = "@" + matrix[0].Substring(1);
                return matrix;
            }
        }
 
        return matrix;
    }
 
    // Function to check if the current word can be placed vertically
    static List<string> CheckVertical(int x, int y, List<string> matrix, string currentWord)
    {
        int n = currentWord.Length;
 
        for (int i = 0; i < n; i++)
        {
            if (matrix[x + i][y] == '#' || matrix[x + i][y] == currentWord[i])
            {
                matrix[x + i] = matrix[x + i].Remove(y, 1).Insert(y, currentWord[i].ToString());
            }
            else
            {
                // Word cannot be placed vertically
                matrix[0] = "@" + matrix[0].Substring(1);
                return matrix;
            }
        }
 
        return matrix;
    }
 
    // Function to solve the crossword puzzle recursively
    static void SolvePuzzle(List<string> words, List<string> matrix, int index, int n)
    {
        if (index < words.Count)
        {
            string currentWord = words[index];
            int maxLen = n - currentWord.Length;
 
            // Loop to check words that can align vertically
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j <= maxLen; j++)
                {
                    List<string> temp = CheckVertical(j, i, new List<string>(matrix), currentWord);
 
                    if (temp[0][0] != '@')
                    {
                        SolvePuzzle(words, temp, index + 1, n);
                    }
                }
            }
 
            // Loop to check words that can align horizontally
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j <= maxLen; j++)
                {
                    List<string> temp = CheckHorizontal(i, j, new List<string>(matrix), currentWord);
 
                    if (temp[0][0] != '@')
                    {
                        SolvePuzzle(words, temp, index + 1, n);
                    }
                }
            }
        }
        else
        {
            // Print the crossword puzzle
            Console.WriteLine((ways + 1) + " way to solve the puzzle");
            PrintMatrix(matrix);
            Console.WriteLine();
 
            // Increment the number of ways
            ways++;
            return;
        }
    }
 
    static void Main()
    {
        // Length of the grid
        int n1 = 10;
 
        // Matrix to hold the grid of the puzzle
        List<string> matrix = new List<string>();
 
        // Input of the puzzle grid (n1 x n1)
        matrix.Add("*#********");
        matrix.Add("*#********");
        matrix.Add("*#****#***");
        matrix.Add("*##***##**");
        matrix.Add("*#****#***");
        matrix.Add("*#****#***");
        matrix.Add("*#****#***");
        matrix.Add("*#*######*");
        matrix.Add("*#********");
        matrix.Add("***#######");
 
        List<string> words = new List<string>();
 
        // Words to be filled in the grid
        words.Add("PUNJAB");
        words.Add("JHARKHAND");
        words.Add("MIZORAM");
        words.Add("MUMBAI");
 
        // Initialize the number of ways to solve the puzzle to zero
        ways = 0;
 
        // Recursive function to solve the puzzle
        SolvePuzzle(words, new List<string>(matrix), 0, n1);
        Console.WriteLine("Number of ways to fill the grid is " + ways);
    }
}


Javascript




// JavaScript program for the above approach
 
// Ways to calculate the number of
// Possible ways to fill the grid
let ways = 0;
 
// This function is used to print
// The resultant matrix
function printMatrix(matrix, n) {
  for (let i = 0; i < n; i++) {
    console.log(matrix[i]);
  }
}
 
// this function checks for the current word
// if it can be placed horizontally or not
// x -> it represent index of row
// y -> it represent index of column
// currentWord -> it represent the
// current word in word array
function checkHorizontal(x, y, matrix, currentWord) {
  const n = currentWord.length;
 
  for (let i = 0; i < n; i++) {
    if (matrix[x][y + i] === '#' || matrix[x][y + i] === currentWord[i]) {
      matrix[x] = matrix[x].slice(0, y + i) + currentWord[i] + matrix[x].slice(y + i + 1);
    } else {
 
      // This shows that word cannot
      // Be placed horizontally
      matrix[0] = "@";
      return matrix;
    }
  }
  return matrix;
}
 
 
// this function checks for the current word
// if it can be placed vertically or not
// x -> it represent index of row
// y -> it represent index of column
// currentWord -> it represent the
// current word in word array
function checkVertical(x, y, matrix, currentWord) {
  const n = currentWord.length;
 
  for (let i = 0; i < n; i++) {
    if (matrix[x + i][y] === '#' || matrix[x + i][y] === currentWord[i]) {
      matrix[x + i] = matrix[x + i].slice(0, y) + currentWord[i] + matrix[x + i].slice(y + 1);
    } else {
 
      // This shows that word
      // Cannot be placed vertically
      matrix[0] = "@";
      return matrix;
    }
  }
  return matrix;
}
 
 
// this function recursively checks for every
// word that can align vertically in one loop
// and in another loop it checks for those words
// that can align horizontally words -> it
// contains all the words to fill in a crossword
// puzzle matrix -> it contain the current
// state of crossword index -> it represent
// the index of current word n -> it represent
// the length of row or column of the square matrix
function solvePuzzle(words, matrix, index, n) {
  if (index < words.length) {
    const currentWord = words[index];
    const maxLen = n - currentWord.length;
 
    // Loop to check the words that can align vertically.
    for (let i = 0; i < n; i++) {
      for (let j = 0; j <= maxLen; j++) {
        const temp = checkVertical(j, i, [...matrix], currentWord);
        if (temp[0] !== "@") {
          solvePuzzle(words, temp, index + 1, n);
        }
      }
    }
 
    // Loop to check the words that can align horizontally.
    for (let i = 0; i < n; i++) {
      for (let j = 0; j <= maxLen; j++) {
        const temp = checkHorizontal(i, j, [...matrix], currentWord);
        if (temp[0] !== "@") {
          solvePuzzle(words, temp, index + 1, n);
        }
      }
    }
  } else {
 
    // Calling of print function to
    // Print the crossword puzzle
    console.log(`${ways + 1} way to solve the puzzle`);
    printMatrix(matrix, n);
    console.log();
 
    // Increase the ways
    ways += 1;
    return;
  }
}
 
// Driver Code
// Length of grid
const n1 = 10;
 
// Matrix to hold the grid of puzzle
const matrix = [];
 
// Take input of puzzle in matrix
// Input of grid of size n1 x n1
matrix.push("*#********");
matrix.push("*#********");
matrix.push("*#****#***");
matrix.push("*##***##**");
matrix.push("*#****#***");
matrix.push("*#****#***");
matrix.push("*#****#***");
matrix.push("*#*######*");
matrix.push("*#********");
matrix.push("***#######");
 
// The words matrix will hold all
// The words need to be filled in the grid
const words = [];
words.push("PUNJAB");
words.push("JHARKHAND");
words.push("MIZORAM");
words.push("MUMBAI");
 
// Initialize the number of ways
// To solve the puzzle to zero
ways = 0;
     
 
// Recursive function to solve the puzzle
// Here 0 is the initial index of words array
// n1 is length of grid
solvePuzzle(words, matrix, 0, n1);
console.log("Number of ways to fill the grid is " + ways);
 
// This code is contributed by princekumaras


Output

1 way to solve the puzzle 
*J********
*H********
*A****P***
*R#***U#**
*K****N***
*H****J***
*A****A***
*N*MUMBAI*
*D********
***MIZORAM

Number of ways to fill the grid is 1


Last Updated : 19 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads