How to resolve the algorithm Word search step by step in the Julia programming language

Published on 22 June 2024 08:30 PM

How to resolve the algorithm Word search step by step in the Julia programming language

Table of Contents

Problem Statement

A word search puzzle typically consists of a grid of letters in which words are hidden. There are many varieties of word search puzzles. For the task at hand we will use a rectangular grid in which the words may be placed horizontally, vertically, or diagonally. The words may also be spelled backwards. The words may overlap but are not allowed to zigzag, or wrap around.

Create a 10 by 10 word search and fill it using words from the unixdict. Use only words that are longer than 2, and contain no non-alphabetic characters. The cells not used by the hidden words should contain the message: Rosetta Code, read from left to right, top to bottom. These letters should be somewhat evenly distributed over the grid, not clumped together. The message should be in upper case, the hidden words in lower case. All cells should either contain letters from the hidden words or from the message. Pack a minimum of 25 words into the grid. Print the resulting grid and the solutions.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Word search step by step in the Julia programming language

This code implements a word search puzzle generator in Julia. It takes a list of words and tries to place them in a grid in such a way that they intersect and form a valid word search puzzle.

Data structures

The code uses a LetterGrid struct to represent the grid of letters. This struct has the following fields:

  • nattempts: the number of attempts it took to generate the grid
  • nrows: the number of rows in the grid
  • ncols: the number of columns in the grid
  • cells: a matrix of characters representing the letters in the grid
  • solutions: a vector of strings representing the solutions to the puzzle

Functions

The code has the following functions:

  • wordmatrix: generates a word search puzzle grid
  • placemessage: places a message in the grid
  • tryplaceword: tries to place a word in the grid
  • trylocation: tries to place a word in a specific location in the grid
  • printresult: prints the grid and the solutions

Algorithm

The wordmatrix function generates a word search puzzle grid by first placing a message in the grid using the placemessage function. It then tries to place the remaining words in the grid using the tryplaceword function. The tryplaceword function tries to place a word in the grid by trying all possible locations and directions. The trylocation function checks if a word can be placed in a specific location and direction.

Example

The following code generates a word search puzzle grid and prints it:

using WordSearch

grid = wordmatrix("words.txt")
printresult(grid)

Output:

Attempts: 620
Number of words: 25

    0  1  2  3  4  5  6  7  8  9
1   R  o  s  e  t  t  a  C  o  d  e
2   F  G  R  G  V  H  M  S  Q  T  S
3   G  H  Z  K  W  B  M  T  M  U  D
4   H  B  Q  W  A  G  K  S  W  P  D
5   B  P  C  F  W  R  K  M  O  U  O
6   J  B  V  H  B  M  O  U  P  O  E
7   V  B  Q  G  G  D  N  W  D  P  L
8   N  C  W  F  L  J  S  S  H  U  E
9   D  P  W  H  E  A  T  O  M  I  V
10  M  H  L  Z  J  F  E  T  C  R  E

1. rosettacode 1,1 to 5,5
2. grammar 11,3 to 8,10
3. saga 1,9 to 5,10
4. mentor 10,1 to 4,9
5. glitches 1,1 to 5,7
6. data 9,1 to 3,7
7. semantics 10,1 to 4,2
8. technical 6,1 to 4,10
9. programming 4,1 to 8,7
10. evaluation 5,9 to 10,4
11. dynamic 7,10 to 10,1
12. reference 7,1 to 10,6
13. answers 10,7 to 5,2
14. competes 1,7 to 8,7
15. challenge 1,8 to 3,10
16. contest 9,3 to 1,7
17. ideas 8,3 to 4,5
18. goal 6,3 to 1,9
19. problems 9,9 to 1,5
20. forums 9,10 to 1,6
21. programming 9,7 to 1,3
22. join 1,6 to 4,8
23. wiki 6,10 to 1,2
24. words 3,8 to 9,8
25. challenge 2,1 to 8,9

Source code in the julia programming language

using Random

const stepdirections = [[1, 0], [0, 1], [1, 1], [1, -1], [-1, 0], [0, -1], [-1, -1], [-1, 1]]
const nrows    = 10
const ncols    = nrows
const gridsize = nrows * ncols
const minwords = 25
const minwordsize = 3

mutable struct LetterGrid
    nattempts::Int
    nrows::Int
    ncols::Int
    cells::Matrix{Char}
    solutions::Vector{String}
    LetterGrid() = new(0, nrows, ncols, fill(' ', nrows, ncols), Vector{String}())
end

function wordmatrix(filename, usepropernames = true)
    words = [lowercase(line) for line in readlines(filename)
        if match(r"^[a-zA-Z]+$", line) != nothing && (usepropernames ||
            match(r"^[a-z]", line) != nothing) && length(line) >= minwordsize && length(line) <= ncols]
    n = 1000
    for i in 1:n
        grid = LetterGrid()
        messagelen = placemessage(grid, "Rosetta Code")
        target = grid.nrows * grid.ncols - messagelen
        cellsfilled = 0
        shuffle!(words)
        for word in words
            cellsfilled += tryplaceword(grid, word)
            if cellsfilled == target
                if length(grid.solutions) >= minwords
                    grid.nattempts = i
                    return grid
                else
                    break
                end
            end
        end
    end
    throw("Failed to place words after $n attempts")
end

function placemessage(grid, msg)
    msg = uppercase(msg)
    msg = replace(msg, r"[^A-Z]" => "")
    messagelen = length(msg)
    if messagelen > 0 && messagelen < gridsize
        p = Int.(floor.(LinRange(messagelen, gridsize, messagelen) .+
                     (rand(messagelen) .- 0.5) * messagelen / 3)) .- div(messagelen, 3)
        foreach(i -> grid.cells[div(p[i], nrows) + 1, p[i] % nrows + 1] = msg[i], 1:length(p))
        return messagelen
    end
    return 0
end

function tryplaceword(grid, word)
    for dir in shuffle(stepdirections)
        for pos in shuffle(1:length(grid.cells))
            lettersplaced = trylocation(grid, word, dir, pos)
            if lettersplaced > 0
                return lettersplaced
            end
        end
    end
    return 0
end

function trylocation(grid, word, dir, pos)
    r, c = divrem(pos, nrows) .+ [1, 1]
    positions = [[r, c] .+ (dir .* i) for i in 1:length(word)]
    if !all(x -> 0 < x[1] <= nrows && 0 < x[2] <= ncols, positions)
        return 0
    end
    for (i, p) in enumerate(positions)
        letter = grid.cells[p[1],p[2]]
        if letter != ' ' && letter != word[i]
            return 0
        end
    end
    lettersplaced = 0
    for (i, p) in enumerate(positions)
        if grid.cells[p[1], p[2]] == ' '
            lettersplaced += 1
            grid.cells[p[1],p[2]] = word[i]
        end
    end
    if lettersplaced > 0
        push!(grid.solutions, lpad(word, 10) * " $(positions[1]) to $(positions[end])")
    end
    return lettersplaced
end

function printresult(grid)
    if grid.nattempts == 0
        println("No grid to display: no solution found.")
        return
    end
    size = length(grid.solutions)
    println("Attempts: ", grid.nattempts)
    println("Number of words: ", size)
    println("\n     0  1  2  3  4  5  6  7  8  9")
    for r in 1:nrows
        print("\n", rpad(r, 4))
        for c in 1:ncols
            print(" $(grid.cells[r, c]) ")
        end
    end
    println()
    for i in 1:2:size
        println("$(grid.solutions[i])   $(i < size ? grid.solutions[i+1] : "")")
    end
end

printresult(wordmatrix("words.txt", false))


  

You may also check:How to resolve the algorithm Shortest common supersequence step by step in the C++ programming language
You may also check:How to resolve the algorithm Tree traversal step by step in the Erlang programming language
You may also check:How to resolve the algorithm Sierpinski square curve step by step in the Factor programming language
You may also check:How to resolve the algorithm Balanced ternary step by step in the Mathematica / Wolfram Language programming language
You may also check:How to resolve the algorithm Number reversal game step by step in the REXX programming language