-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathp98.re
89 lines (82 loc) · 2.14 KB
/
p98.re
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* Nonograms. */
type element =
| Empty
| X;
let rec is_set_range = (row, col0, col1) =>
col0 >= col1 || row[col0] == X && is_set_range(row, col0 + 1, col1);
let is_set_sub = (row, col0, width) =>
col0 + width <= Array.length(row) && is_set_range(row, col0, col0 + width);
let rec check_row = (row, col0, patt_row) =>
if (col0 >= Array.length(row)) {
patt_row == []
} else {
switch row[col0] {
| Empty => check_row(row, col0 + 1, patt_row)
| X =>
switch patt_row {
| [] => false
| [nX, ...tl] =>
if (is_set_sub(row, col0, nX)) {
let col0 = col0 + nX;
(col0 >= Array.length(row) || row[col0] == Empty) && check_row(row, col0 + 1, tl)
} else {
false
}
}
}
};
let rec check_rows = (table, row0, patts_row) =>
row0 >= Array.length(table)
|| (
switch patts_row {
| [patt_row, ...tl] => check_row(table[row0], 0, patt_row) && check_rows(table, row0 + 1, tl)
| [] => assert false
}
);
let char_of_element = (ele) =>
switch ele {
| Empty => '_'
| X => 'X'
};
let print_tbl = (table) => {
let print_row = (r) => {
Array.iter(
(e) => {
print_char('|');
print_char(char_of_element(e))
},
r
);
print_string("|\n")
};
Array.iter(print_row, table)
};
let solve = (patts_row, patts_col) => {
let height = List.length(patts_row)
and width = List.length(patts_col);
let table = Array.make_matrix(height, width, Empty);
let rec gen = (col, row, patts_col) =>
if (col >= width) {
if (check_rows(table, 0, patts_row)) {
print_tbl(table)
}
} else {
switch patts_col {
| [[], ...rest_patt] => gen(col + 1, 0, rest_patt)
| [[nX, ...tl], ...rest_patt] =>
assert (nX > 0);
if (row + nX <= height) {
for (r in row to row + nX - 1) {
table[r][col] = X
};
gen(col, row + nX + 1, [tl, ...rest_patt]);
for (r in row to row + nX - 1) {
table[r][col] = Empty
};
gen(col, row + 1, patts_col)
}
| [] => assert false
}
};
gen(0, 0, patts_col)
};