-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c11dc9f
commit be545e1
Showing
7 changed files
with
153 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
enum Letter = { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z }; % english letters in alphabetical order | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
%%% Variables whose values need to be passed in %%% | ||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|
||
int: n; % board size | ||
int: m; % number of words | ||
|
||
int: max_len; % length of the longest word being passed in | ||
|
||
array [1..m] of int: word_lens; % array giving the length of each word | ||
array [1..m] of int: pivot_inds; % array giving the 0-index the pivot-letter | ||
array [1..m,1..max_len] of Letter: words; % array whose rows are words, with excess length padded with other letters | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|
||
array [1..n,1..n] of var Letter: board; | ||
|
||
array [1..m] of var 1..n: word_pos_y; % values constrained by board size | ||
array [1..m] of var 1..n: word_pos_x; % values constrained by board size | ||
array [1..m] of var -1..1: word_delta_y; % values constrained by {-1,0,1} | ||
array [1..m] of var -1..1: word_delta_x; % values constrained by {-1,0,1} | ||
|
||
|
||
constraint forall(i in 1..m)(word_delta_y[i] != 0 \/ word_delta_x[i] != 0); % at least one of dy,dx must be nonzero | ||
|
||
% Pivot helper functions | ||
function int: num_letters_lt_pivot_idx(int: i) = pivot_inds[i]; | ||
function int: num_letters_gte_pivot_idx(int: i) = word_lens[i] - pivot_inds[i]; | ||
|
||
% For each word, enforce that its last letter lies within the board. | ||
% Since its first letter also lies within the board, this implies that the entire word lies within the board, by convexity. | ||
constraint forall(i in 1..m)( | ||
% End-of-word constraints | ||
word_pos_y[i]+word_delta_y[i]*(num_letters_gte_pivot_idx(i)-1) >= 1 | ||
/\ word_pos_y[i]+word_delta_y[i]*(num_letters_gte_pivot_idx(i)-1) <= n | ||
/\ word_pos_x[i]+word_delta_x[i]*(num_letters_gte_pivot_idx(i)-1) >= 1 | ||
/\ word_pos_x[i]+word_delta_x[i]*(num_letters_gte_pivot_idx(i)-1) <= n | ||
% Start-of-word constraints | ||
/\ word_pos_y[i]-word_delta_y[i]*num_letters_lt_pivot_idx(i) >= 1 | ||
/\ word_pos_y[i]-word_delta_y[i]*num_letters_lt_pivot_idx(i) <= n | ||
/\ word_pos_x[i]-word_delta_x[i]*num_letters_lt_pivot_idx(i) >= 1 | ||
/\ word_pos_x[i]-word_delta_x[i]*num_letters_lt_pivot_idx(i) <= n | ||
); | ||
|
||
% Link the words to the board by linking letters to board positions. | ||
constraint forall(i in 1..m)( | ||
forall(j in (-1*num_letters_lt_pivot_idx(i)+1)..num_letters_gte_pivot_idx(i))( | ||
words[i,num_letters_lt_pivot_idx(i)+j] = board[word_pos_y[i] + word_delta_y[i]*(j-1), word_pos_x[i] + word_delta_x[i]*(j-1)] | ||
) | ||
); | ||
|
||
% Search the variables in order of decreasing word length (words are passed in as shortest-to-longest). | ||
% For each word first search the positions in min-to-max order (intuition: start from the left/top of the board then work your way in). | ||
% Then search the orientations in horizontal-to-diagonalmax order (intuition: diagonal words interfere with more other words) | ||
|
||
annotation pos_var_strat; | ||
annotation pos_val_strat; | ||
|
||
% Define position searches and orientation searches separately, then interleave them in reverse order. | ||
solve :: seq_search([ | ||
if x = 1 then int_search([word_pos_y[i], word_pos_x[i]], pos_var_strat, pos_val_strat) | ||
else int_search([word_delta_y[i], word_delta_x[i]], first_fail, indomain_median) | ||
endif | i in reverse(1..m), x in 1..2]) | ||
satisfy; | ||
|
||
|
||
% Function which outputs, for a given board position, whether there is a word which overlaps that position | ||
function bool: square_is_covered(int: i, int: j) = | ||
exists(k in 1..m)( | ||
exists(l in (-1*num_letters_lt_pivot_idx(k)+1)..num_letters_gte_pivot_idx(k))( | ||
(i == fix(word_pos_y[k]) + fix(word_delta_y[k])*(l-1)) /\ (j == fix(word_pos_x[k]) + fix(word_delta_x[k])*(l-1)) | ||
) | ||
); | ||
|
||
output [ if square_is_covered(i,j) then format(fix(board[i,j])) else "_" endif ++ | ||
if j == n then "\n" else " " endif | i,j in 1..n ] ++ ["\n"]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,10 @@ | ||
n = 15; | ||
m = 51; | ||
|
||
y_pos_map = [ 8, 9, 9, 8, 7, 7, 7, 8, 9, 10, 10, 10, 10, 9, 8, 7, 6, 6, 6, 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 10, 9, 8, 7, 6, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; | ||
x_pos_map = [ 8, 8, 9, 9, 9, 8, 7, 7, 7, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 6, 6, 6, 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 10, 9, 8, 7, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]; | ||
m = 50; | ||
|
||
max_len = 6; | ||
word_lens = [ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 ]; | ||
max_freq_idx = [ 1, 1, 2, 1, 0, 1, 2, 2, 3, 1, 1, 1, 2, 1, 3, 1, 2, 2, 2, 1, 3, 3, 2, 4, 1, 4, 3, 1, 2, 3, 4, 2, 3, 2, 1, 1, 1, 4, 2, 1, 3, 1, 5, 0, 1, 3, 3, 3, 5, 0, 1 ]; | ||
words = [| T, E, S, T, A, A | B, A, S, H, A, A | B, E, A, N, A, A | S, E, E, D, A, A | A, G, O, N, A, A | G, A, L, A, A, A | Q, U, A, L, A, A | K, H, A, T, A, A | C, O, L, A, A, A | M, I, L, K, A, A | M, I, L, L, A, A | B, E, E, R, A, A | C, O, R, N, A, A | C, A, K, E, A, A | S, O, D, A, A, A | F, E, T, E, A, A | C, H, A, I, A, A | T, R, E, E, A, A | B, R, E, W, A, A | J, A, V, A, A, A | W, I, N, E, A, A | C, O, K, E, A, A | P, L, A, N, T, A | C, O, C, O, A, A | R, E, V, E, L, A | F, E, R, I, A, A | U, M, B, E, R, A | P, A, R, T, Y, A | F, E, A, S, T, A | S, U, G, A, R, A | M, O, C, H, A, A | E, V, E, N, T, A | B, R, E, A, D, A | C, H, E, E, R, A | L, A, T, T, E, A | D, R, I, N, K, A | B, R, O, W, N, A | J, U, I, C, E, A | S, N, A, C, K, A | Y, E, M, E, N, A | D, E, C, A, F, A | E, A, S, T, E, R | F, I, E, S, T, A | A, C, I, D, I, C | V, E, N, I, C, E | P, A, R, A, D, E | B, A, N, A, N, A | A, F, F, A, I, R | P, E, R, S, I, A | A, F, R, I, C, A | C, A, N, C, E, R |]; | ||
word_lens = [ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 ]; | ||
pivot_inds = [ 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 3, 3 ]; | ||
words = [| S, A, G, A, Z, Z | T, I, M, E, Z, Z | P, A, G, E, Z, Z | L, O, F, T, Z, Z | Y, O, R, E, Z, Z | B, O, O, K, Z, Z | N, E, W, S, Z, Z | E, P, I, C, Z, Z | H, O, U, R, Z, Z | M, A, T, H, Z, Z | T, A, L, E, Z, Z | M, Y, T, H, Z, Z | P, L, O, T, Z, Z | L, I, F, E, Z, Z | C, L, O, C, K, Z | S, I, X, T, Y, Z | L, E, V, E, L, Z | S, T, U, D, Y, Z | P, I, E, C, E, Z | T, H, I, N, G, Z | D, R, A, M, A, Z | W, H, I, L, E, Z | F, L, O, O, R, Z | J, I, F, F, Y, Z | F, A, B, L, E, Z | N, O, V, E, L, Z | A, T, T, I, C, Z | W, R, O, T, E, Z | S, K, I, L, L, Z | S, C, O, O, P, Z | M, O, V, I, E, Z | T, R, U, T, H, Z | S, L, E, E, P, Z | B, A, T, H, O, S | N, A, T, U, R, E | H, O, R, A, R, Y | S, T, O, R, E, Y | M, I, D, D, A, Y | A, L, W, A, Y, S | M, O, M, E, N, T | R, E, P, O, R, T | C, L, I, M, A, X | A, N, N, A, L, S | W, I, T, E, L, O | L, E, G, E, N, D | C, E, L, L, A, R | R, E, C, O, R, D | T, I, M, I, S, T | G, A, R, R, E, T | M, I, N, U, T, E |]; | ||
|
||
pos_var_strat = first_fail; | ||
pos_val_strat = indomain_median; |
Oops, something went wrong.