Detecting closed loop in a 2D array pattern - javascript

Let's assume that you get the following array:
foo = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,0,0],
[0,0,0,1,0,0,0,1,0,0],
[0,0,0,1,0,0,0,1,0,0],
[0,0,0,1,1,1,0,1,0,0],
[0,0,0,0,0,1,0,1,0,0],
[0,0,0,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
]
How can I determine if the pattern of 1s is a closed loop? I have struggled with this for a few days. I have tried a recursive loop to find neighbors and words, but when you have a more complex pattern it won't work, for example:
foo = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,0,0,0,0],
[0,0,0,1,0,1,0,0,0,0],
[0,0,0,1,0,1,0,0,0,0],
[0,0,0,1,1,1,1,1,0,0],
[0,0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
]
Do someone have a magic algorithm to solve this ? :(

As Dagrooms said, try to find 1(s) with only one adjacent 1. Code looks like:
function isValid1(x,y){
return (foo[x-1][y] + foo[x+1][y] + foo[x][y-1] + foo[x][y + 1])>1;
}
function validLoop(){
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
if(foo[i][j] === 1 && !isValid1(i,j)) {
return false;
}
}
}
return true;
}
where rows and columns are the 2d array size.
UPDATE
This will return true if there is at least one closed loop:
function numTouching1(x,y){
return foo[x - 1][y] + foo[x + 1][y] + foo[x][y - 1] + foo[x][y + 1];
}
function validLoop(){
var n = 0, x = 0; // x is current point's number of touching 1 and n is total
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
if(foo[i][j] === 1) {
x = numTouching1(i, j) - 2;
if(x === -1 || x === 1 || x === 2){
n += x;
}
}
}
}
return n > -1;
}
JSFiddle: https://jsfiddle.net/AdminXVII/b0f7th5d/
UPDATE 2
Extract the loop(s):
function numTouching1(x,y){
return foo[x - 1][y] + foo[x + 1][y] + foo[x][y - 1] + foo[x][y + 1];
}
function extractLoop(){
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
if(foo[i][j] === 1 && numTouching1(i, j) === 1){
foo[i][j] = 0;
extractLoop();break;
}
}
}
}
JSFiddle: https://jsfiddle.net/AdminXVII/b0f7th5d/7/
UPDATE 3
This is to threat if there's more than one loop, thougth for one loop it's slower.
function numTouching1(x, y) {
return foo[x - 1][y] + foo[x + 1][y] + foo[x][y - 1] + foo[x][y + 1];
}
function extractLoop() {
for (var i = 0; i < rows; i++) {
for (var j = 0; j < columns; j++) {
if (foo[i][j] === 1 && numTouching1(i, j) === 1) {
foo[i][j] = 0;
extractLoop(); break;
}
}
}
}
function validLoop(){
extractLoop();
for(var i = 0; i < rows; i++){
for(var j = 0; j < columns; j++){
if(foo[i][j] === 1 && numTouching1(i,j) == 2) {
return true;
}
}
}
return true;
}
JSFiddle: https://jsfiddle.net/AdminXVII/w7zcgpyL/
UPDATE 4
Safer numTouching1() method:
function numTouching1(x, y) {
return ((x > 0) ? foo[x - 1][y] : 0) + ((x < rows-1) ? foo[x + 1][y] : 0) + ((y > 0) ? foo[x][y - 1] : 0) + ((y < columns-1) ? foo[x][y + 1] : 0);
}
Modified previous JSFiddle

Related

JavaScript pyramid

I'm trying to print a pyramid that has odd numbers for edges. For example output should be:
.......5
...3,4,3
1,2,3,2,1
(dots are here just to show formating)
I managed to write:
function p(n){
let string = "";
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= n - i; j++) {
string += " " ;
}
for (let k = 1; k <= 2*i-1; k++) {
string += n-k +1;
}
string += "\n";
}
console.log(string);
}
p(5);
But I'm not sure how to continue to get wanted result
You can try it :
function p(n){
let string = ""
for (let i = 0; i <= n/2; i++) {
let k = n - 2 * i
for (let j =0; j < Math.floor(n/2)*2 + 1; j++) {
if(j < Math.floor(n/2) - i) {
string += " ";
}
if( j >= Math.floor(n/2) - i && j <= Math.floor(n/2) + i) {
string += k;
j < Math.floor(n/2) ? k++ : k--
}
if(j > Math.floor(n/2) + i ) {
string += " ";
}
}
string += "\n";
}
console.log(string);
}
p(7);

nested for loops in js, incremented by 2

I am currently trying to solve the xmas tree problem, with internal tree-like shape.
issue is with internal spacing, it supposed to be like: 1, 5, 7, 9. Instead it is 1, 3, 4, 5. I do not know, how to increment s loop by 2 in each loop turn.
/*
*********
**** ****
*** ***
** **
* *
*********
*/
function drawTree(h) {
let n = h + 3;
for (var i = 1; i <= 1; i++) {
var temp = "";
for (var j = 1; j <= n; j++) {
temp = temp + "*";
}
console.log(temp);
}
for (var i = 0; i < h - 2; i++) {
var tree = '';
console.log("\n");
for (var k = 3; k <= h - i; k++) {
tree += "*";
};
tree += "s";
for (var k = 1; k <= i; k++) {
for (var k = 1; k <= i; k++) {
tree += "s";
};
tree += "s";
};
for (var k = 3; k <= h - i; k++) {
tree += "*";
};
console.log(tree);
};
console.log("\n");
let g = h + 3;
for (var i = 1; i <= 1; i++) {
var temp = "";
for (var j = 1; j <= g; j++) {
temp = temp + "*";
}
console.log(temp);
}
};
drawTree(6);
function drawTree(stars, rowLength) {
for (let row = 0; row < rowLength; row++) {
if (row === 0) {
console.log("*".repeat(stars));
} else if(row === rowLength - 1) {
console.log("*".repeat(stars));
} else {
let spaces = 2 * row - 1;
if (spaces > stars) {
spaces = stars;
}
let numStarsInRow = "*".repeat((stars - spaces) / 2);
console.log(numStarsInRow + " ".repeat(spaces) + numStarsInRow);
}
}
}
drawTree(9, 5)
You can implement this by nesting loops over the height and the width of the tree, noting that the output is a * whenever:
it's the first or last row; or
the current x position is less than or equal to the halfway point minus the row number; or
the current x position is greater than or equal to the halfway point plus the row number
For all other cases the output is a space. For example:
function drawTree(height) {
// compute the width of the tree from the height
let width = height % 2 ? height + 2 : height + 3;
// find the halfway point
let half = (width - 1) / 2;
for (let i = 0; i < height; i++) {
let l = '';
for (let j = 0; j < width; j++) {
if (i == 0 || // first row
i == height - 1 || // last row
j <= (half - i) || // left side
j >= (half + i) // right side
) {
l += '*';
}
else {
l += ' ';
}
}
console.log(l);
}
}
drawTree(6);
drawTree(5);

Where i make mistake here?

Hello everyone i have a problem with my code and i'm not sure how to do this , i need to write code that draw this in console:
Draw '*' in every even number
For that i need to use nested loops.
So far i have only this:
var n = 5;
var stars = '';
for (var i = 1; i <= n; i++) {
var starsline = '';
for (var j = 1; j <= n; j++) {
console.log(i + j);
}
if ( i % 2 === 0){
starsline += '2';
} else {
starsline += '1'
}
stars += starsline;
}
console.log(stars);
This numbers 2 and 1 are only to check if the number is even or odd.
Just a few things:
1) you got some weird bracket here:
/*}*/ if ( i % 2 === 0){
which causes a syntax error later on.
2) you actually log the right thing:
console.log(i + j)
but you dont use it. Just put that into your condition:
if((i + j) % 2 === 0)
and you are done :)
let size = 5, stars = "";
for (var row = 1; row <= size; row++) {
var starsline = "";
for (var col = 1; col <= size; col++){
if ((row + col) % 2 === 0){
starsline += '*';
} else {
starsline += ' ';
}
stars += starsline + "\n";
}
console.log(stars);
I think what you tried to do is something like this:
var n = 5;
var stars = '';
for (var i = 1; i <= n; i++) {
var starsline = '';
for (var j = 1; j <= n; j++){
if ( (i + j) % 2 === 0){
// used three spaces for consistency in the drawing
starsline += ' ';
} else {
starsline += ' * '
}
}
stars += starsline + '\n';
}
console.log(stars);
Try this:
var n = 5;
var stars = '';
for (var i = 1; i <= n; i++)
{
var starsline = '';//<-- reset the value of line
if ( i % 2 === 0)//<--this identifies which line will the stars be created
{
starsline += '* * *';//<--creating the stars on each line
}
else
{
starsline += ' * * ';//<--creating the stars on each line
}
stars += starsline+'\n';//<-- '\n' add line breaks for each lines
}
console.log(stars);//<-- print the stars

JavaScript (for/while)

In result I should get a spiral matrix but it's not working.The problem is somewhere in the 3rd or 4th for from while
The for loop is just not working. I think, logically, the problem is solved and I have just a syntax problem but I can't find it.
For example the matrix should look like this:
n=3 n=5
1 2 3 1 2 3 4 5
8 9 4 16 17 18 19 6
7 6 5 15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
n = parseInt(prompt('N:', '5'));
A = new Array();
for (i = 0; i < n; i++) {
A[i] = new Array();
for (j = 0; j < n; j++) A[i][j] = 0;
}
DIM = parseInt(n * n);
//A[i][j]=1;
//==========================
document.write("<br>Matrix: <table border='2'>".fontcolor('red'));
for (i = 0; i < n; i++) {
document.write("<tr>");
for (j = 0; j < n; j++) {
document.write("<td >" + A[i][j] + " ");
}
document.write("<br>");
}
document.write("</table>");
document.write("========================================== <br>");
//===========================
k = 1;
nr = 1;
f = true;
while (f) {
i = k - 1;
for (j = k - 1; j <= n - k; j++) {
if (nr <= DIM) {
A[i][j] = nr;
nr++;
document.write(A[i][j] + ' ');
} else {
f = false;
};
};
document.write('<br>');
for (i = k; i <= n - k; i++) {
if (nr <= DIM) {
A[i][j] = nr;
nr++;
document.write(A[i][j] + ' ');
} else {
f = false;
};
};
document.write('<br>');
for (j = (n - k - 1); j >= (k - 1); j--) {
if (nr <= DIM) {
A[i][j] = nr;
nr++;
document.write(A[i][j] + ' ');
} else {
f = false;
};
};
document.write('<br>');
for (i = (n - k - 1); i >= k; i--) {
if (nr <= DIM) {
A[i][j] = nr;
nr++;
document.write(A[i][j] + ' ');
} else {
f = false;
};
};
document.write('<br>');
k++;
};
//=====================================
document.write("<br>Matrix: <table border='2'>".fontcolor('red'));
for (i = 0; i < n; i++) {
document.write("<tr>");
for (j = 0; j < n; j++) {
document.write("<td >" + A[i][j] + " ");
}
document.write("<br>");
}
document.write("</table>");
document.write("========================================== <br>");
It's not a syntax error. It's crashing on A[i][j] = nr; in the for (j = (n - k - 1); j >= (k - 1); j--) { for loop when you try to set A[5][3] = 10; because A[5] is undefined.
That should solve you immediate problem though I doubt that helps much... This is a legitimately tricky programming problem. A spiral seems so simple but it's actually quite hard. I'd highly recommend you take Quince's advice and improve your variable names. Trying to get this code to work would give anyone a headache.

Finding the rank of the Given string in list of all possible permutations with Duplicates

I was trying to find the Rank of the given string in the list of permutations and was hoping someone can find the bug.
function permute() {
var W = $('input').val(),
C = [];
for (var i = 0; i < 26; i++) C[i] = 0;
var rank = 1;
for (var i = 0; i < W.length; i++) {
C[W.charCodeAt(i) - 'a'.charCodeAt(0)]++;
}
var repeated= 1;
for (var i = 0; i < C.length; i++) {
if(C[i] > 0) {
repeated *= fact(C[i]);
}
}
if (W !== '') {
for (var i = 0; i < W.length; i++) {
//How many characters which are not used, that come before current character
var count = 0;
for (var j = 0; j < 26; j++) {
if (j == (W.charCodeAt(i) - 'a'.charCodeAt(0))) break;
if (C[j] > 0) count++;
}
C[W.charCodeAt(i) - 'a'.charCodeAt(0)] = 0;
rank += ( count * fact(W.length - i - 1) );
}
rank = rank/ repeated;
}
var pp = 'Rank of :: ' + W + ' -- ' + rank;
$('div').append('<p>' + pp + '</p>');
}
function fact(n) {
if (n == 0 || n == 1) return 1;
else return fact(n - 1) * n;
}
$('button').click(permute);
Check Fiddle
A use case for this might be
bookkeeper is supposed to give a rank of 10743.
Here's the demo:
For each position check how many characters left have duplicates, and use the logic that if you need to permute n things and if 'a' things are similar the number of permutations is n!/a!

Categories