How can pre-define a length of maze path when generating maze - javascript

I am trying create a maze of words with pre-defined length of found path, But have no clue about what algorithm would make it possible.
For ex: I want the length from cells start 1 to end [2] should be 11( the length of "onetwothree").
Here is the current code I am using to generate the maze:
var demotext = "onetwothree";
var widthmaze = (demotext.length + 5) / 2 + 1;
var heightmaze = (demotext.length + 5) / 2 - 1;
document.getElementById('out').innerHTML = display(maze(widthmaze, heightmaze));
function maze(x, y) {
var n = x * y - 1;
if (n < 0) {
alert("illegal maze dimensions");
return;
}
var horiz = [];
for (var j = 0; j < x + 1; j++) horiz[j] = [],
verti = [];
for (var j = 0; j < x + 1; j++) verti[j] = [],
here = [Math.floor(Math.random() * x), Math.floor(Math.random() * y)],
path = [here],
unvisited = [];
for (var j = 0; j < x + 2; j++) {
unvisited[j] = [];
for (var k = 0; k < y + 1; k++)
unvisited[j].push(j > 0 && j < x + 1 && k > 0 && (j != here[0] + 1 || k != here[1] + 1));
}
while (0 < n) {
var potential = [
[here[0] + 1, here[1]],
[here[0], here[1] + 1],
[here[0] - 1, here[1]],
[here[0], here[1] - 1]
];
var neighbors = [];
for (var j = 0; j < 4; j++)
if (unvisited[potential[j][0] + 1][potential[j][1] + 1])
neighbors.push(potential[j]);
if (neighbors.length) {
n = n - 1;
next = neighbors[Math.floor(Math.random() * neighbors.length)];
unvisited[next[0] + 1][next[1] + 1] = false;
if (next[0] == here[0])
horiz[next[0]][(next[1] + here[1] - 1) / 2] = true;
else
verti[(next[0] + here[0] - 1) / 2][next[1]] = true;
path.push(here = next);
} else
here = path.pop();
}
return {
x: x,
y: y,
horiz: horiz,
verti: verti
};
}
function display(m) {
var text = [];
for (var j = 0; j < m.x * 2 + 1; j++) {
var line = [];
if (0 == j % 2)
for (var k = 0; k < m.y * 4 + 1; k++)
if (0 == k % 4)
line[k] = '+';
else
if (j > 0 && m.verti[j / 2 - 1][Math.floor(k / 4)])
line[k] = ' ';
else
line[k] = '-';
else
for (var k = 0; k < m.y * 4 + 1; k++)
if (0 == k % 4)
if (k > 0 && m.horiz[(j - 1) / 2][k / 4 - 1])
line[k] = ' ';
else
line[k] = '|';
else
if (2 == k % 4)
line[k] = demotext[Math.floor(Math.random() * demotext.length)];
else
line[k] = ' ';
if (0 == j) {line[1] = line[3] = ' '; line[2] = '1'};
if (m.x * 2 - 1 == j) line[4 * m.y] = '2';
text.push(line.join('') + '\r\n');
}
return text.join('');
}
<pre id="out"></pre>
Moving start and end point to make the path length match with text maybe the solution but I do not know how to implement it. Any help would be great !
Ps: I would like the result can be like this:

Related

using Damerau-Levenshtein distance to compare sets of text in code.org

Not very knowledgeable with coding, I usually use block coding and not typing.
I've used many different Levenshtein distance codes I've found online and most of them didn't work for one reason or another
var levDist = function (s, t) {
var d = []; //2d matrix
// Step 1
var n = s.length;
var m = t.length;
if (n == 0) return m;
if (m == 0) return n;
//Create an array of arrays in javascript (a descending loop is quicker)
for (var i = n; i >= 0; i--) d[i] = [];
// Step 2
for (i = n; i >= 0; i--) d[i][0] = i;
for (var j = m; j >= 0; j--) d[0][j] = j;
// Step 3
for (i = 1; i <= n; i++) {
var s_i = s.charAt(i - 1);
// Step 4
for (j = 1; j <= m; j++) {
//Check the jagged ld total so far
if (i == j && d[i][j] > 4) return n;
var t_j = t.charAt(j - 1);
var cost = (s_i == t_j) ? 0 : 1; // Step 5
//Calculate the minimum
var mi = d[i - 1][j] + 1;
var b = d[i][j - 1] + 1;
var c = d[i - 1][j - 1] + cost;
if (b < mi) mi = b;
if (c < mi) mi = c;
d[i][j] = mi; // Step 6
//Damerau transposition
if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) {
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
}
}
}
// Step 7
return d[n][m];
};
This is all the code I’ve written (including the most recent attempt of getting the levenshtein distance)
var levDist = function (s, t) {
var d = []; //2d matrix
// Step 1
var n = s.length;
var m = t.length;
if (n == 0) return m;
if (m == 0) return n;
//Create an array of arrays in javascript (a descending loop is quicker)
for (var i = n; i >= 0; i--) d[i] = [];
// Step 2
for (i = n; i >= 0; i--) d[i][0] = i;
for (var j = m; j >= 0; j--) d[0][j] = j;
// Step 3
for (i = 1; i <= n; i++) {
var s_i = s.charAt(i - 1);
// Step 4
for (j = 1; j <= m; j++) {
//Check the jagged ld total so far
if (i == j && d[i][j] > 4) return n;
var t_j = t.charAt(j - 1);
var cost = (s_i == t_j) ? 0 : 1; // Step 5
//Calculate the minimum
var mi = d[i - 1][j] + 1;
var b = d[i][j - 1] + 1;
var c = d[i - 1][j - 1] + cost;
if (b < mi) mi = b;
if (c < mi) mi = c;
d[i][j] = mi; // Step 6
//Damerau transposition
if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) {
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
}
}
}
// Step 7
return d[n][m];
};
var S = "Hello World";
var grossWPM;
var Transparency = 1;
var Timer = 60;
var InitialTime = Timer;
var Texts = getColumn("Texts", "Texts");
var TextLength = getColumn("Texts", "Number of Characters");
var Title = getColumn("Texts", "Titles");
var Author = getColumn("Texts", "Authors");
var TextSelector = randomNumber(0, 19);
console.log("Article #" + (TextSelector + 1));
console.log(TextLength[TextSelector] + " Characters in total");
console.log(Title[TextSelector]);
console.log("By: " + Author[TextSelector]);
var Countdown;
var Countdown = 6;
//Texts are obtained from
//https://data.typeracer.com/pit/texts
onEvent("button1", "click", function( ) {
timedLoop(1000, function() {
Countdown = Countdown - 1;
setText("button1", Countdown - 0);
timedLoop(100, function() {
setText("text_area2", "");
});
if (Countdown <= 1) {
stopTimedLoop();
setTimeout(function() {
setText("button1", "GO!");
setText("text_area1", Texts[TextSelector]);
if (getText("button1") == "GO!") {
var TransparentLoop = timedLoop(100, function() {
Transparency = Transparency - 0.1;
setProperty("Warning", "text-color", rgb(77,87,95, Transparency));
if (Transparency <= 0) {
deleteElement("Warning");
showElement("label2");
stopTimedLoop(TransparentLoop);
}
});
var TimerLoop = timedLoop(1000, function() {
Timer = Timer - 1;
setText("label2", Timer);
if (Timer <= 0) {
grossWPM = (TextLength[TextSelector] / 5) / ((InitialTime - Timer) / 60);
console.log(grossWPM);
setScreen("screen2");
if (Timer == 1) {
S = " second";
} else {
S = " seconds";
}
setText("label1", "Your typing speed was approximately " + (Math.round(grossWPM) + (" WPM* with " + (Timer + (S + " left")))));
stopTimedLoop(TimerLoop);
}
});
console.log("Timer Started");
timedLoop(10, function() {
var str = getText("text_area2");
if (str.length == TextLength[TextSelector]) {
stopTimedLoop(TimerLoop);
grossWPM = (TextLength[TextSelector] / 5) / ((InitialTime - Timer) / 60);
setScreen("screen2");
levDist(str, Texts[TextSelector]);
if (Timer == 1) {
S = " second";
} else {
S = " seconds";
}
setText("label1", "Your typing speed was approximately " + (Math.round(grossWPM) + (" WPM* with " + (Timer + (S + " left")))));
if (grossWPM == 69) {
setText("label4", "Nice");
}
stopTimedLoop();
}
});
}
}, 1000);
}
});
});
Obviously not that good at this so can anyone help?
I want to compare two sets of text
Something the user types in.
Paragraph that the user was supposed to type.
This is for a WPM test and I want a way to get a measurement for WPM that includes errors the user makes while typing.
If there is a way to check this besides the Levenshtein distance please tell me, I just looked up a way to do that and Levenshtein distance seemed like the way to do so
The error given by code.org says:
ERROR: Line: 50: TypeError: d[n] is undefined
I fixed the issue, I used this code
function levenshtein(s1, s2) {
if (s1 == s2) {
return 0;
}
var s1_len = s1.length;
var s2_len = s2.length;
if (s1_len === 0) {
return s2_len;
}
if (s2_len === 0) {
return s1_len;
}
// BEGIN STATIC
var split = false;
try {
split = !('0')[0];
} catch (e) {
// Earlier IE may not support access by string index
split = true;
}
// END STATIC
if (split) {
s1 = s1.split('');
s2 = s2.split('');
}
var v0 = new Array(s1_len + 1);
var v1 = new Array(s1_len + 1);
var s1_idx = 0,
s2_idx = 0,
cost = 0;
for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) {
v0[s1_idx] = s1_idx;
}
var char_s1 = '',
char_s2 = '';
for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) {
v1[0] = s2_idx;
char_s2 = s2[s2_idx - 1];
for (s1_idx = 0; s1_idx < s1_len; s1_idx++) {
char_s1 = s1[s1_idx];
cost = (char_s1 == char_s2) ? 0 : 1;
var m_min = v0[s1_idx + 1] + 1;
var b = v1[s1_idx] + 1;
var c = v0[s1_idx] + cost;
if (b < m_min) {
m_min = b;
}
if (c < m_min) {
m_min = c;
}
v1[s1_idx + 1] = m_min;
}
var v_tmp = v0;
v0 = v1;
v1 = v_tmp;
}
return v0[s1_len];
}
and I got that code from this question
This is levenshtein distance NOT damerau-levenshtein distance

Javascript Memoization in Browser Not Seeing Speed Up

I am attempting to memoize a function in javascript, to be run in browser, client side. Writing this function in R (the language I am most comfortable using). In R, I see significant benefits from using memoization (4 minutes run time to 0.02 seconds for P_n(7/10, 20, 15, 6, 1) ). When I rewrite the function in javascript, I see almost no benefit. What is the problem with my javascript code (or am I going about this the wrong way entirely)?
Below are the memoized functions in R and javascript respectively. The R function (first of the two) runs very fast compared to the naive recursion, while javascript essentially sees no difference. Some amount of memoization is happening, however, because if I run the exact same function call twice, i.e. P_memo(7/10, 20, 15, 6, 1) and then P_memo(7/10, 20, 15, 6, 1) again, the second call takes 0 time. The first call should be dramatically quicker due to re-use of intermediate calls in the recursion.
P_n <- (function() {
# Memoization handled through the use of cache
cache <- NULL
cache_reset <- function() {
cache <<- new.env(TRUE, emptyenv())
}
cache_set <- function(key, value) {
assign(key, value, envir = cache)
}
cache_get <- function(key) {
get(key, envir = cache, inherits = FALSE)
}
cache_has_key <- function(key) {
exists(key, envir = cache, inherits = FALSE)
}
# Initialize the cache
cache_reset()
# This is the function that gets returned by the anonymous function and
# becomes P_n
function(rho, n, i, k, s) {
nc <- paste(rho, n, i, k, s)
# Handle "vectors" by element
if(length(n) > 1){
return(lapply(n, function(n) sapply(n, P_n, rho = rho, i = 1:(n+k), k = k, s = s)))
}
if (length(i) > 1) {
return(sapply(i, P_n, rho = rho, n = n, k = k, s = s))
}
# Cached cases
if (cache_has_key(nc))
return(cache_get(nc))
# Everything else
#proposition 1
if(i == (n+k)){
#print('Proposition 1')
if(k >= s){
return((rho / (rho + 1))^n)
}else if( (k+n) <= s){
product_iter = 1
for(j in 1:n){
product_iter = product_iter * ( rho + (k + j - 1)/s )
}
out = rho^n / product_iter
cache_set(nc, out)
return(out)
}else if( k < s & s < (k + n)){
product_iter2 = 1
for(j in 1:(s-k)){
product_iter2 = product_iter2 * ( rho + (k + j - 1)/s )
}
product_denom = ((rho + 1)^(n-s+k)) * product_iter2
out = rho^n / product_denom
cache_set(nc, out)
return(out)
}
}
#proposition 2
else if(k == 0 & n == i){
#print('Proposition 2')
if(n <= s){
product_iter11 = 1
for(j in 1:n){
product_iter11 = product_iter11 * (rho + (j - 1)/s)
}
return(rho^n / product_iter11)
}else if(n > s){
product_iter12 = 1
for(j in 1:s){
product_iter12 = product_iter12 * ( rho + (j - 1)/s )
}
product_denom12 = ((rho + 1)^(n-s)) * product_iter12
out = rho^n / product_denom12
cache_set(nc, out)
return(out)
}
}
#if i = 1
else if(i == 1){
upsum = 0
for(j in 2:(n + k)){
upsum = upsum + P_n(rho, n, j, k, s)
}
out = 1 - upsum
cache_set(nc, out)
return(out)
}
#proposition 3
else if(n == 1 & 2 <= i & i <= k){
#print('Proposition 3')
if(k <= s){
begin = rho / (rho + (i - 1)/s)
product_iter13 = 1
for(j in 1:(k-i+1)){
product_iter13 = product_iter13 * (1 - rho / (rho + (k - j + 1)/s) )
}
out = begin * product_iter13
cache_set(nc, out)
return(out)
}else if(k > s & i > s){
out = rho / (rho+1)^(k-i+2)
cache_set(nc, out)
return(out)
}else if(i <= s & s <= k){
begin2 = rho / (( rho + 1 )^(k - s + 1) * ( rho + (i - 1)/s))
product_iter14 = 1
for(j in 1:(s-i)){
product_iter14 = product_iter14 * (1 - rho / (rho + (s - j)/s) )
}
out = begin2 * product_iter14
cache_set(nc, out)
return(out)
}
}
#proposition 4
else if( n >= 2 & 2 <= i & i <= (k + n - 1)){
#print('Proposition 4')
if(i>s){
begin11 = rho/(rho+1)
product_iter21 = 0
for(j in (i-1):(k+n-1)){
product_iter21 = product_iter21 + (1 / (rho+1))^(j-i+1) * P_n(rho, n-1, j, k, s)
}
out = begin11 * product_iter21
cache_set(nc, out)
return(out)
}else if(i <= s){
begin12 = rho / (rho + (i-1)/s)
summer1 = 0
for(j in (i-1):(s-1)){
product_iter22 = 1
for(h in 1:(j-i+1)){
product_iter22 = product_iter22 * (1 - rho / (rho + (j - h + 1) / s))
}
summer1 = summer1 + product_iter22 * P_n(rho, n-1, j, k, s)
}
product_iter23 = 1
for(h in 1:(s-i)){
product_iter23 = product_iter23 * (1 - rho / (rho + (s-h) / s))
}
summer2 = 0
for(j in s:(k+n-1)){
summer2 = summer2 + ((1 / (rho + 1))^(j-s+1) * P_n(rho, n-1, j, k, s))
}
bottom = product_iter23 * summer2
inner = summer1 + bottom
out = begin12 * inner
cache_set(nc, out)
return(out)
}
}
#check if missed all propositions
else{
stop("No proposition detected")
}
}
})()
var P_memo = (function() {
var memo = {};
var slice = Array.prototype.slice;
function f(rho, n, i, k, s){
var args = slice.call(arguments);
var value;
if (args in memo) {
return(memo[args]);
}else{
// NOTES ON THE UNITS OF INPUTS
//rho: ratio of lambda / tau
// n: arrival of nth customer
// i: are i customers in queue
// k : number of customers at t = 0
// s: machines in use
//proposition 1
if(i == (n+k)){
//print('Proposition 1')
if(k >= s){
return(Math.pow(rho / (rho + 1), n));
}else if( (k+n) <= s){
var product_iter = 1;
for(var j=1; j<= n; j++){
product_iter = product_iter * ( rho + (k + j - 1)/s );
}
return(Math.pow(rho, n) / product_iter);
}else if( k < s && s < (k + n)){
var product_iter2 = 1;
for(var j=1; j<= s-k; j++){
product_iter2 = product_iter2 * ( rho + (k + j - 1)/s );
}
product_denom = Math.pow((rho + 1), (n-s+k)) * product_iter2;
return(Math.pow(rho, n) / product_denom);
}
}
//proposition 2
else if(k == 0 && n == i){
if(n <= s){
var product_iter11 = 1;
for(var j=1; j<= n; j++){
product_iter11 = product_iter11 * (rho + (j - 1)/s);
}
return(Math.pow(rho, n) / product_iter11);
}else if(n > s){
var product_iter12 = 1;
for(var j=1; j<= s; j++){
product_iter12 = product_iter12 * ( rho + (j - 1)/s );
}
product_denom12 = Math.pow((rho + 1), (n-s)) * product_iter12;
return(Math.pow(rho, n) / product_denom12);
}
}
//if i = 1
else if(i == 1){
var upsum = 0;
for(var j=2; j<= (n+k); j++){
upsum = upsum + f(rho, n, j, k, s);
}
return(1 - upsum);
}
//proposition 3
else if(n == 1 && 2 <= i && i <= k){
if(k <= s){
begin = rho / (rho + (i - 1)/s);
var product_iter13 = 1;
for(var j=1; j<= (k-i+1); j++){
product_iter13 = product_iter13 * (1 - rho / (rho + (k - j + 1)/s) );
}
return(begin * product_iter13);
}else if(k > s && i > s){
return(rho / Math.pow((rho+1), (k-i+2)));
}else if(i <= s && s <= k){
begin2 = rho / (Math.pow( (rho + 1), (k - s + 1)) * ( rho + (i - 1)/s));
var product_iter14 = 1;
for(var j=1; j<= (s-i); j++){
product_iter14 = product_iter14 * (1 - rho / (rho + (s - j)/s) );
}
return(begin2 * product_iter14);
}
}
//proposition 4
else if( n >= 2 && 2 <= i && i <= (k + n - 1)){
if(i>s){
begin11 = rho/(rho+1);
var product_iter21 = 0;
for(var j=(i-1); j<= (k+n-1); j++){
product_iter21 = product_iter21 + Math.pow((1 / (rho+1)),(j-i+1)) * f(rho, n-1, j, k, s);
}
return(begin11 * product_iter21);
}else if(i <= s){
begin12 = rho / (rho + (i-1)/s);
var summer1 = 0;
for(var j=(i-1); j<= (s-1); j++){
var product_iter22 = 1;
for(var h=1; h<=(j-1+1); h++){
product_iter22 = product_iter22 * (1 - rho / (rho + (j - h + 1) / s));
}
summer1 = summer1 + product_iter22 * f(rho, n-1, j, k, s);
}
var product_iter23 = 1;
for(var h=1; h<=(s-i); h++){
product_iter23 = product_iter23 * (1 - rho / (rho + (s-h) / s));
}
var summer2 = 0;
for(var j=s; j<= (k+n-1); j++){
summer2 = summer2 + (Math.pow((1 / (rho + 1)), (j-s+1)) * f(rho, n-1, j, k, s)) ;
}
bottom = product_iter23 * summer2;
inner = summer1 + bottom;
return(begin12 * inner);
}
}
}
}
//Closure of f(), self-executing anonymous function
return f;
})();
Your memoization has two flaws:
(1) You never add results to memo.
(2) args in memo casts args to a string. That will work for an array of numbers, but it might fail for other inputs.
I'd write a generic version of memo like this:
const memo = fn => {
const cache = {};
return (...args) => {
const key = JSON.stringify(args);
if(key in memo) return memo[key];
return memo[key] = fn(...args);
};
};
const memoizedF = memo(f);

Having issues with clearing area around blank squares in minesweeper

Ok i finally got my minesweeper game made just needing one more thing if anyone could help me with. The part when you click on an unnumbered square and it will reveal some of the board. I have been playing around on this for sometime just drawing a blank. This is a simple minesweeper game just in java script. I have everything labeled where things should go to make it easier to find and i will bold it on where my code ive been working on is.
//Global
//store the value of each square
var gaValue = new Array(8)
for (i = 0; i <= 8; i++)
gaValue[i] = new Array(8)
for (i = 0; i <= 8; i++)
{
//loop through each item in those row
for (j = 0; j <= 8 ; j++)
gaValue[i][j] = 0
}
//Store the status of each square
var gaSquare = new Array(8)
for (j = 0; j <= 8; j++)
gaSquare[j] = new Array(8)
for (j = 0; j <= 8; j++)
{
//loop through each item in those row
for (i = 0; i <= 8 ; i++)
gaSquare[i][j] = "C"
}
//Track of whether the game is over or not (starts this with false)
var gbGameOver = false
function vInit()
{
var strHTML
var i
var j
strHTML = "<table style='margin-left:auto;margin-right:auto'>"
strHTML += "<tr><td colspan='8' style='text-align:center'>MineSweeper</td></tr>"
strHTML += "<tr><td colspan='8' style='text-align:center'><input type='button' id='btnNew' value='New Game' onclick='vNewGame()'></td></tr>"
//Loop through the rows to build the table of tiles
for (i = 0; i < 8; i++)
{
strHTML += "<tr>"
for (j = 0; j < 8; j++)
strHTML += '<td><img src="images/sqt0.png" id="square' + i + ', ' + j + '" onclick="vClick(' + i + ', ' + j + ')"/></td>';
strHTML += "<tr>";
}
strHTML += '<tr><td colspan="8" style="text-align:center"><textarea id="taOut" cols="18" rows="10"></textarea></td></tr>'
strHTML += "</table>"
frmGrid.innerHTML = strHTML
//Place bombs
var iBomb = 0
var iRow = Math.floor(Math.random() * 8)
var iCol = Math.floor(Math.random() * 8)
while (iBomb < 8)
{
while (gaValue[iRow][iCol] == 9)
{
iRow = Math.floor(Math.random() * 8)
iCol = Math.floor(Math.random() * 8)
}
gaValue[iRow][iCol] = 9
iBomb++
}
//Calculate clue values around mines
var iMine = 0
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
for (k = (i - 1) ; k <= (i + 1) ; k++)
for (m = (j - 1) ; m <= (j + 1) ; m++)
if (k >= 0 && k <= 9 && j >= 0 && j <= 9)
if (gaValue[k][m] == 9)
iMine++
if (gaValue[i][j] != 9)
gaValue[i][j] = iMine
iMine = 0
}
}
}
//Get the ID of the image I need to change
function vClick(iRow, iCol)
{
var gaSquare = "square" + iRow + ", " + iCol
var strOut = ""
gaSquare[iRow][iCol] = 'o';
document.getElementById(gaSquare).src = "images/" + gaValue[iRow][iCol] + ".png"
if (gaValue[iRow][iCol] == 9)
{
gbGameOver = true
strOut = "Game Over"
vOver()
}
else if (gaValue[iRow][iCol] == 0)
vZero(iRow, iCol)
document.getElementById('taOut').value = strOut
}
//GameOver
function vOver()
{
var i
var j
var strID;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++) {
strID = "square" + i + ", " + j;
document.getElementById(strID).src = "images/" + gaValue[i][j] + ".png"
}
}
**//Clearing area
function vZero(iRow, iCol, i, j) {
for (i = iRow - 1; i <= iRow + 1; i++) {
for (j = iCol - 1; j <= iCol + 1; j++) {
if (k >= 0 && k <= 8 && j >= 0 && j <= 8)
vClick(i, j)
}**
//Start new game
function vNewGame() {
vInit()
}
//no menu on right click
function bIsRightButtonClicked(e) {
var rightclick = false
e = e || window.event
if (e.which) {
rightclick = (e.which == 3)
}
else if (e.button) {
rightclick = (e.button == 2)
}
return rightclick
}
}
}
I believe the main mistake is that you are referring to k inside vZero() when that variable is not defined. You also appear to be missing a closing curly bracket or two on that function.
Try changing that function to as follows:
//Clearing area
function vZero(iRow, iCol) {
for (var i = iRow - 1; i <= iRow + 1; i++) {
for (var j = iCol - 1; j <= iCol + 1; j++) {
if (i >= 0 && i <= 8 && j >= 0 && j <= 8) vClick(i, j);
}
}
}
You'll note that I changed the i and j parameters to be local variables, because they are only used by that function for the purposes of the for loops. You don't need to have them as parameters. Doing so only confuses other developers because that implies that you need to pass a value for them into the function for it to work, whereas you only need to pass in iRow and iCol. Does that make sense?

Create range of letters and numbers

I'm creating a form where users can input a range. They are allowed to input letters and numbers. Some sample input:
From: AA01
To: AZ02
Which should result in:
AA01
AA02
AB01
AB02
And so on, till AZ02
And:
From: BC01
To: DE01
Should result in:
BC01
BD01
BE01
CC01
CD01
CE01
Etc
I managed to get it working for the input A01 to D10 (for example)
jsFiddle
However, i can't get it to work with multiple letters.
JS code:
var $from = $('input[name="from"]');
var $to = $('input[name="to"]');
var $quantity = $('input[name="quantity"]');
var $rangeList = $('.rangeList');
var $leadingzeros = $('input[name="leadingzeros"]');
$from.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$to.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$leadingzeros.on('click', function () {
updateQuantity();
});
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
if (xl != null && yl != null && xl[0].length > 0 && yl[0].length > 0) {
xl = xl[0].toUpperCase();
yl = yl[0].toUpperCase();
$rangeList.html('');
var a = yl.charCodeAt(0) - xl.charCodeAt(0);
for (var i = 0; i <= a; i++) {
if (!isNaN(x) && !isNaN(y)) {
if (x <= y) {
var z = (y - x) + 1;
$quantity.val(z * (a + 1));
$rangeList.html('');
for (var b = z; b > 0; b--) {
var c = ((y - b) + 1);
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(String.fromCharCode(65 + i) + c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
}
} else if (!isNaN(x) && !isNaN(y)) {
if (x < y) {
var z = (y - x) + 1;
$quantity.val(z);
$rangeList.html('');
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
$rangeList.html('');
for (var i = 0; i < result.length; i++) {
$rangeList.append(result[i] + '<br />');
}
}
function leadingZeroes(number, size) {
number = number.toString();
while (number.length < size) number = "0" + number;
return number;
}
This is perfect for a recursive algorithm:
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
return result;
}
Called as follows:
createRange('BC01', 'DE02'); // Generates an array containing all values expected
EDIT: Amended function below to match new test case (much more messy, however, involving lots of type coercion between strings and integers).
function prefixZeroes(value, digits) {
var result = '';
value = value.toString();
for (var i = 0; i < digits - value.length; i++) {
result += '0';
}
return result + value;
}
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
if (from.charCodeAt(0) < 65) {
fromInt = parseInt(from);
toInt = parseInt(to);
length = toInt.toString().length;
var innerRange = createRange(from.substring(length), to.substring(length));
for (var i = fromInt; i <= toInt; i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(prefixZeroes(i, length) + innerRange[j]);
}
}
} else {
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
}
return result;
}
Please note that because of your strict logic in how the value increments this method requires exactly 4 characters (2 letters followed by 2 numbers) to work. Also, this might not be as efficient/tidy as it can be but it took some tinkering to meet your logic requirements.
function generate(start, end) {
var results = [];
//break out the start/end letters/numbers so that we can increment them seperately
var startLetters = start[0] + start[1];
var endLetters = end[0] + end[1];
var startNumber = Number(start[2] + start[3]);
var endNumber = Number(end[2] + end[3]);
//store the start letter/number so we no which value to reset the counter to when a maximum boundry in reached
var resetLetter = startLetters[1];
var resetNumber = startNumber;
//add first result as we will always have at least one
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
//maximum while loops for saefty, increase if needed
var whileSafety = 10000;
while (true) {
//safety check to ensure while loop doesn't go infinite
whileSafety--;
if (whileSafety == 0) break;
//check if we have reached the maximum value, if so stop the loop (break)
if (startNumber == endNumber && startLetters == endLetters) break;
//check if we have reached the maximum number. If so, and the letters limit is not reached
//then reset the number and increment the letters by 1
if (startNumber == endNumber && startLetters != endLetters) {
//reset the number counter
startNumber = resetNumber;
//if the second letter is at the limit then reset it and increment the first letter,
//otherwise increment the second letter and continue
if (startLetters[1] == endLetters[1]) {
startLetters = '' + String.fromCharCode(startLetters.charCodeAt(0) + 1) + resetLetter;
} else {
startLetters = startLetters[0] + String.fromCharCode(startLetters.charCodeAt(1) + 1);
}
} else {
//number limit not reached so just increment the number counter
startNumber++;
}
//add the next sequential value to the array
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
}
return results;
}
var results = generate("BC01", "DE01");
console.log(results);
Here is a working example, which uses your second test case
Using #Phylogenesis' code, i managed to achieve my goal.
jsFiddle demo
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
var r = createRange(xl[0], yl[0]);
var z = (y - x) + 1;
if (x <= y) {
for (var j = 0; j < r.length; j++) {
var letters = r[j];
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
if (i == z) {
r[j] = letters + c + '<br />';
} else {
j++;
r.splice(j, 0, letters + c + '<br />');
}
}
}
} else {
for (var i = 0; i < r.length; i++) {
r[i] += '<br />';
}
}
$quantity.val(r.length);
$rangeList.html('');
for (var i = 0; i < r.length; i++) {
$rangeList.append(r[i]);
}
}
This works for unlimited letters and numbers, as long as the letters are first.
Thanks for your help!

What I do in javascript to get my required result?

Here is my javascript code
for (var i = 1; i <= _MAXPAGECOUNT - 2; i++) {
e = document.getElementsByName("q" + i + "[]");
for (var j = 0; j <= e.length - 1; j++) {
if (e[j].checked) {
result = result + "," + i + ":" + e[j].value;
// break;
}
}}
The problem is this, it shows result like this 1:2,1:3,1:4,2:3,2:4,2:5
here in code i means question number and j means answer number, but I want to result as like this 1:2,3,4 ; 2:3,4,5
Try this
for (var i = 1; i <= _MAXPAGECOUNT - 2; i++) {
result = result+i+":";
e = document.getElementsByName("q" + i + "[]");
for (var j = 0; j <= e.length - 1; j++) {
if (e[j].checked) {
result = result + e[j].value;
// break;
}
}
if(i<_MAXPAGECOUNT - 2)
{
result = result+" ; ";
}
}

Categories

Resources