-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathredoku.js
116 lines (94 loc) · 2.29 KB
/
redoku.js
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
var redoku = (function() {
var alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ'.split('');
var generateRegex = (function() {
var ZERO_LENGTH_GOTCHAS = [
// TODO: Maybe up the ante with lookaheads here...
'.*', '.?', '[RR]*', 'R*', 'R?' //, '(R|R)?', 'R?(?=[0RR])'
];
var ONE_CLASS = [
'[R0R]',
'[R]?0',
'0?',
'[0]',
'0R*',
'0'
];
var TWO_CLASS = [
'[R10]+',
'0[R1R]',
'[R0]1',
'(01|RR)',
'(RR|01)',
'[1R0][1R]',
'[1RR0]+',
'R?[10R]+'
];
var THREE_CLASS = [
'[2R10]+',
'[102R]+',
'0R*1[R2]',
'R?0+1[2R]',
'[1R2R0]+',
'[2R]?[120R]+'
];
function boolRand() {
return Math.random() > .5;
}
function esc(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}
return function(chars, avoidSet) {
// Characters that we can randomly use:
var availableRandom = alpha.join('').replace(
// Take out `chars` if no `avoidSet` is defined:
RegExp('[' + esc((avoidSet||chars).join('')) + ']+', 'g'), ''
).split('');
var r = '';
for (var i = 0, l = chars.length; i < l; i++) {
var nextChars = chars.slice(i);
if (boolRand()) r += use(ZERO_LENGTH_GOTCHAS, nextChars);
if (boolRand() && i + 2 < l) {
r += use(THREE_CLASS, nextChars);
i += 2;
} else if (i + 1 < l) {
r += use(TWO_CLASS, nextChars);
i += 1;
} else {
r += use(ONE_CLASS, nextChars);
}
}
function use(a, chars) {
return a[0 | Math.random () * a.length].replace(/\w/g, function($) {
switch ($) {
case 'R': return esc(availableRandom[0 | Math.random() * availableRandom.length]);
default: return esc(chars[+$]);
}
});
}
return r;
}
}());
return function(r, c) {
var answers = Array(r*c+1).join().split('').map(function() {
return alpha[0 | Math.random() * alpha.length];
});
var rHeaders = [], cHeaders = [];
for (var ri = 0; ri < r; ++ri) {
var rowChars = answers.slice(ri*c, c+ri*r);
// console.log(rowChars, ri, r, c);
rHeaders.push( generateRegex(rowChars) );
}
for (var ci = 0; ci < c; ++ci) {
var colChars = [];
for (var ri = 0; ri < r; ++ri) {
colChars.push( answers[ri*c+ci] );
}
cHeaders.push( generateRegex(colChars) );
}
return {
cols: cHeaders,
rows: rHeaders,
ans: answers
}
};
}());