import std.random : Random, uniform, randomShuffle; import std.stdio; immutable int[][] dirs = [ [1, 0], [ 0, 1], [ 1, 1], [1, -1], [-1, 0], [0, -1], [-1, -1], [-1, 1] ]; enum nRows = 10; enum nCols = 10; enum gridSize = nRows * nCols; enum minWords = 25; auto rnd = Random(); class Grid { int numAttempts; char[nRows][nCols] cells; string[] solutions; this() { for(int row=0; row= 3 && line.length <= maxlen) { if (all!isAlpha(line)) { words ~= line.toLower.idup; } } } return words; } Grid createWordSearch(string[] words) { Grid grid; int numAttempts; outer: while(++numAttempts < 100) { randomShuffle(words); grid = new Grid(); int messageLen = placeMessage(grid, "Rosetta Code"); int target = gridSize - messageLen; int cellsFilled; foreach (string word; words) { cellsFilled += tryPlaceWord(grid, word); if (cellsFilled == target) { if (grid.solutions.length >= minWords) { grid.numAttempts = numAttempts; break outer; } else break; // grid is full but we didn't pack enough words, start over } } } return grid; } int placeMessage(Grid grid, string msg) { import std.algorithm : filter; import std.ascii : isUpper; import std.conv : to; import std.string : toUpper; msg = to!string(msg.toUpper.filter!isUpper); if (msg.length > 0 && msg.length < gridSize) { int gapSize = gridSize / msg.length; for (int i=0; i 0) { return lettersPlaced; } } } return 0; } int tryLocation(Grid grid, string word, int dir, int pos) { import std.format; int r = pos / nCols; int c = pos % nCols; int len = word.length; // check bounds if ((dirs[dir][0] == 1 && (len + c) > nCols) || (dirs[dir][0] == -1 && (len - 1) > c) || (dirs[dir][1] == 1 && (len + r) > nRows) || (dirs[dir][1] == -1 && (len - 1) > r)) { return 0; } int i, rr, cc, overlaps = 0; // check cells for (i=0, rr=r, cc=c; i 0) { grid.solutions ~= format("%-10s (%d,%d)(%d,%d)", word, c, r, cc, rr); } return lettersPlaced; } void printResult(Grid grid) { if (grid is null || grid.numAttempts == 0) { writeln("No grid to display"); return; } int size = grid.solutions.length; writeln("Attempts: ", grid.numAttempts); writeln("Number of words: ", size); writeln("\n 0 1 2 3 4 5 6 7 8 9"); for (int r=0; r