4 by 4 Sudoku game - processing

I have an assignment that is making a processing sketch that make 4 by 4 Sudoku game and make the player enter the missing numbers to the playing grid, the problem that I'm facing now is to make a loop or something that allow the player to enter ALL the missing numbers ?
I'd Succeeded to allow the player to enter the first 4 numbers using switch statement and if statement but the program only go through the first if statement from each case, and I want to make it go through the rest ?
here is the cod that I make.
void setup ()
{
background (255);
size (125,125);
board();
}
void cell (int x , int y , int s )
{
rect (x,y,s,s);
}
void triple (int x , int y , int s )
{
for (int i = 0 ; i < 2 ; i ++)
{
cell ( x,y,s);
x += s;
}
}
void block (int x , int y , int s )
{
for (int i = 0 ; i < 2 ; i ++)
{
triple ( x , y , s);
y += s;
}
}
void row (int x , int y , int s )
{
for ( int i = 0 ; i < 2 ; i ++)
{
block ( x , y , s);
x += (s*2);
}
}
void cellArray ( int x , int y , int s)
{
for (int i = 0 ; i < 2 ; i ++)
{
row ( x , y , s);
y += (s*2);
}
}
void darwLines ( int x , int y , int s)
{
strokeWeight (3);
for (int i = 0 ; i < 1 ; i ++)
{
x += (s*2);
line ( x , 0 , x , (s*4));
}
for ( int j = 0 ; j < 1 ; j ++)
{
y += (s*2);
line ( 0 , y , (s*4) , y );
}
strokeWeight (1);
}
void board ()
{
cellArray (0,0,30);
darwLines (0,0,30);
}
void draw ()
{
int [][] fixedArray = new int [4][4];
fill (0);
textSize(28);
for (int i = 0 ; i < 4 ; i ++)
{
for (int j = 0 ; j < 4 ; j ++)
{
fixedArray [0][2] = 3;
fixedArray [1][1] = 4;
fixedArray [2][2] = 4;
fixedArray [3][3] = 3;
text(fixedArray [0][2], 65,25);
text(fixedArray [1][1],35,58);
text(fixedArray [2][2],65,88);
text(fixedArray [3][3],95,117);
}//end of inner loop.
}//end of outter loop.
if (mousePressed)
{
mouseClicked ();
}
}
/*------------------------------------------------------------------------------------------*/
void mouseClicked ()
{
int s = 30 ;
int cellX = mouseX / s;
int cellY = mouseY / s;
int [][] userInputArray = new int [4][4];
for (int m = 0 ; m < 4 ; m ++)
{
for (int n = 0 ; n < 4 ; n ++)
{
switch (key)
{
case '1':
if (mouseX > userInputArray [0][0] -s && mouseX < userInputArray [0][0]+s && mouseY > userInputArray [0][0] -s && mouseY < userInputArray [0][0] +s )
{
fill (0,0,255);
text (key , 10,25);
}
else if (mouseX > userInputArray [1][2] -30 && mouseX < userInputArray [1][2]+30 && mouseY > userInputArray [1][2] -30 && mouseY < userInputArray [1][2] +30)
{
fill (0,0,255);
text ('1' , 65,58);
}
else if (mouseX > userInputArray [2][3] -30 && mouseX < userInputArray [2][3]+30 && mouseY > userInputArray [2][3] -30 && mouseY < userInputArray [2][3] +30)
{
fill (0,0,255);
text('1' ,95,88);
}
else if (mouseX > userInputArray [3][1] -30 && mouseX < userInputArray [3][1]+30 && mouseY > userInputArray [3][1] -30 && mouseY < userInputArray [3][1] +30)
{
fill (0,0,255);
text('1' ,35,117);
}
break ;
case '2':
if (mouseX > userInputArray [0][1] -(s-s) && mouseX < userInputArray [0][1]+(s*2) && mouseY > userInputArray [0][1] -s && mouseY < userInputArray [0][1] +s )
{
fill (0,0,255);
text(key ,35,25);
}
else if (mouseX > userInputArray [1][3] - (s-s) && mouseX < userInputArray [1][3] +(s*2) && mouseY > userInputArray [1][3] -(s*2) && mouseY < userInputArray [1][3] +(s*2))
{
fill(0,0,255);
text(key,95,58);
}
else if (mouseX > userInputArray [2][0] -(s-s) && mouseX < userInputArray [2][0] +(s*2) && mouseY > userInputArray [2][0] -(s*2) && mouseY < userInputArray [2][0] +(s*2))
{
fill(0,0,255);
text(key,10,88);
}
else if (mouseX > userInputArray [3][2] -(s-s) && mouseX < userInputArray [3][2] +(s*2) && mouseY > userInputArray [3][2] -(s*2) && mouseY < userInputArray [3][2] +(s*2))
{
fill(0,0,255);
text(key,65,117);
}
break;
case '3':
if ( mouseX > userInputArray [1][0] -s && mouseX < userInputArray [1][0]+s && mouseY > userInputArray [1][0] -(s-s) && mouseY < userInputArray [1][0] +(s*2))
{
fill(0,0,255);
text(key,10,58);
}
else if (mouseX > userInputArray [2][1] -s && mouseX < userInputArray [2][1]+s && mouseY > userInputArray [2][1] -(s-s) && mouseY < userInputArray [2][1] +(s*2))
{
fill(0,0,255);
text(key,35,88);
}
break ;
case '4':
if (mouseX > userInputArray [0][3] +60 && mouseX < userInputArray [0][3]+120 && mouseY > userInputArray [0][3] -30 && mouseY < userInputArray [0][3] +30 )
{
fill(0,0,255);
text(key,95,25);
}
else if (mouseX > userInputArray [3][0] +60 && mouseX < userInputArray [3][0]+120 && mouseY > userInputArray [3][0] -30 && mouseY < userInputArray [3][0] +30 )
{
fill(0,0,255);
text(key,10,117);
}
break;
default :
{
fill (255);
rect ((cellX * s),(cellY*s),s,s);
}
}//end of switch.
}//end of the inner loop.
}//end of the outter for loop.
}

I have gone through your code, and observed some issues:
First of all, the code is quite messy. The drawlines + cellArray + row + ... can be solved much more elegantly, without the need for such a complex nesting of functions.
Apparently, you want fixedArray to always remain constant. Therefore, you don't need to define it and assign values at every draw loop. You can move that declaration to the beginning of your code.
Same happens with userInputArray, values are defined nowhere, and therefore equal 0.
You are drawing each number 16 times on top of itself, that's why it looks so crancky... There is no need for the nested for loops when drawing the text.
This said, please find attached a proposal of enhanced code. It fixes all the issues, is more flexible if in need if changing sudoku size and position, and is in general more consistent code.
Nevertheless, if you want to make this really interesting, try to figure out how to make random value generation, so that every sudoku is different from the previous one! There are plenty of sudoku generation algorithms online.
Good luck!
// GLOBAL VARS DECLARATION
int[][] resultsValue = {
{1,2,3,4},
{3,4,1,2},
{2,3,4,1},
{4,1,2,3}};
boolean[][] resultsSolved = new boolean[4][4];
int cellsX = 4;
int cellsY = 4;
float cellSize = 30;
float xPos = 0;
float yPos = 0;
void setup ()
{
background (255);
size (130, 130);
smooth();
// GLOBAL VARS VALUE ASSIGNMENT
resultsSolved[0][2] = true;
resultsSolved[1][1] = true;
resultsSolved[2][2] = true;
resultsSolved[3][3] = true;
}
void draw ()
{
background(255);
drawBoard(cellsX, cellsY, cellSize, xPos, yPos, 2);
pushStyle();
fill (0);
textSize(28);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (resultsSolved[i][j] == true) {
text(resultsValue[i][j], 5 + xPos + j * cellSize, -5 + yPos + (i + 1) * cellSize);
}
}
}
popStyle();
if (mousePressed)
{
mouseClicked ();
}
}
/*------------------------------------------------------------------------------------------*/
void drawBoard(int rows, int cols, float cellSize, float xPos, float yPos, int cellBlocks) {
pushStyle();
noFill();
stroke(0);
strokeWeight(1);
// DRAW RECTANGLES
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
rect(xPos + i * cellSize, yPos + j * cellSize, cellSize, cellSize);
}
}
strokeWeight(3);
// DRAW LINES
for (int i = 0; i < cols / cellBlocks; i++) {
line(xPos + i * cellSize * cellBlocks, yPos, xPos + i * cellSize * cellBlocks, yPos + rows * cellSize);
}
for (int i = 0; i < rows / cellBlocks; i++) {
line(xPos, yPos + i * cellSize * cellBlocks, xPos + cols * cellSize, yPos + i * cellSize * cellBlocks);
}
popStyle();
}
void mouseClicked ()
{
int cellX = (int) ((mouseX - xPos) / cellSize);
if (cellX > cellsX - 1) cellX = cellsX - 1;
else if (cellX < 0) cellX = 0;
int cellY = (int) ((mouseY - yPos) / cellSize);
if (cellY > cellsY - 1) cellY = cellsY - 1;
else if (cellY < 0) cellY = 0;
int lastKeyInt = int(key - '0');
if (resultsValue[cellY][cellX] == lastKeyInt) {
resultsSolved[cellY][cellX] = true;
}
}

Related

Store Item color value for every pixel p5js

I made a grid where i can draw every pixel using the get and store function
and now I want to store also the color value every time I change the color from the color picker. Right now all the cells on the grid are affected when I choose a color instead of staying in e.g. red when I choose red and stay red when I choose green.
Below is the code:
let sizewidth = 17
let sizeheight = 17
function setup() {
createCanvas(sizewidth*30, sizeheight*30);
col = createColorPicker('#000000');
}
function draw() {
background(255);
for(y = 0; y < sizeheight; y++){
for(x = 0; x < sizewidth; x++){
if(getItem(x + ":" + y) == null){
storeItem(x + ":" + y, false)
}
if(getItem(x + ":" + y) == true){
fill(col.color());
}
rect(x*30, y*30, 30, 30)
noFill()
}
}
}
function mouseClicked(){
for(y = 0; y < sizeheight; y++){
for(x = 0; x < sizewidth; x++){
if(mouseX < x*30+30 && mouseX > x*30 && mouseY < y*30+30 && mouseY > y*30){
storeItem(x + ":" + y, true)
}
}
}
}
function keyTyped(){
if(key == "c"){
clearStorage()
}
}
I think that you can store the color data instead of boolean value, like this:
let sizewidth = 17
let sizeheight = 17
function setup() {
clearStorage() // clearing the previous boolean data (can be deleted later)
createCanvas(sizewidth*30, sizeheight*30);
col = createColorPicker('#000000');
}
function draw() {
background(255);
for(y = 0; y < sizeheight; y++){
for(x = 0; x < sizewidth; x++){
if(getItem(x + ":" + y) == null){
storeItem(x + ":" + y, [255,255,255]) // filling all white
}
else {
let c = getItem(x + ":" + y); // getting color
fill(c[0],c[1],c[2]); // fill cell with the color
}
rect(x*30, y*30, 30, 30)
noFill()
}
}
}
function mouseClicked(){
for(y = 0; y < sizeheight; y++){
for(x = 0; x < sizewidth; x++){
if(mouseX < x*30+30 && mouseX > x*30 && mouseY < y*30+30 && mouseY > y*30){
let c = col.color();
storeItem(x + ":" + y, [red(c),green(c),blue(c)]); // storing the color
}
}
}
}
function keyTyped(){
if(key == "c"){
clearStorage()
}
}

processing error (It looks like you're mixing "active" and "static" modes.)

It looks like you're mixing "active" and "static" modes. I want to play two figures different direction. I am a beginner and need help in understanding what to do wiht the error.
int x,y;
int diam;
int xdir;
int z,r;
int zdir;
int extent;
void setup(){
size(600, 400);
x = 300;
y = 100;
diam = 30;
xdir = +4;
fill(#000000);
z = 300;
r = 300;
zdir = -4;
extent = 30;
}
void draw(){
background(200);
ellipse(x, y, diam, diam);
x = x + xdir;
if (x + diam/2 > 600){
xdir = xdir * -1;
fill(#e81919);
}
else if (x - diam/2 < 0 ){
xdir = xdir * -1;
fill(#00f22e);
}
}
square (z, r, extent);
z = z + zdir;
if (z + 30 > 600 || z - 30 < 0){
zdir = zdir * -1;
fill(#00f22e);
}
}
You've got an extra curly brace after else if (){}. Should look like this:
void draw() {
background(200);
ellipse(x, y, diam, diam);
x = x + xdir;
if (x + diam/2 > 600) {
xdir = xdir * -1;
fill(#e81919);
} else if (x - diam/2 < 0 ) {
xdir = xdir * -1;
fill(#00f22e);
}
square (z, r, extent);
z = z + zdir;
if (z + 30 > 600 || z - 30 < 0) {
zdir = zdir * -1;
fill(#00f22e);
}
}

Check if object is in range in a matrix

I would like to check if an object is in range in a matrix.
A 1 range would be 9 blocks around the player (orange).
But a two range would be 25 blocks (blue). The player is the red cross.I tried the following code:`
int size = ((range * 2) +1) * ((range * 2) + 1);
int sq = (range * 2) + 1;
int startX = x - range; if (startX < 0) startX = 0;
int startY = y - range; if (startY < 0) startY = 0;
int endX = x + range; if (endX > arrayWitdth) endX = arrayWitdth;
int endY = y + range; if (endY > arrayLenght) endY = arrayLenght;
//printf("Range: %d\n", range);
for (size_t i = startX; i < endX; i++)
{
for (size_t j = startY; j < endY; j++)
{
//printf("Looking at (%d,%d)\n", i, j);
if (map[i][j] == charTocheck) return 1;
}
}
`
You don't check the last block, so the correct implementation would be:
int size = ((range * 2) +1) * ((range * 2) + 1);
int sq = (range * 2) + 1;
int startX = x - range; if (startX < 0) startX = 0;
int startY = y - range; if (startY < 0) startY = 0;
int endX = x + range + 1; if (endX > arrayWitdth) endX = arrayWitdth;
int endY = y + range + 1; if (endY > arrayLenght) endY = arrayLenght;
//printf("Range: %d\n", range);
for (size_t i = startX; i < endX; i++)
{
for (size_t j = startY; j < endY; j++)
{
//printf("Looking at (%d,%d)\n", i, j);
if (map[i][j] == charTocheck) return 1;
}
}
notice that endX and endY have slightly changed.

Finding the biggest square in a rectangle with a condition

In a rectangle with given height and width. I'm supposed to find the square with most 1s and print the number of 1s on stdout, also in that same square there must not be more 2s than half of 1s, i.e:((# of 1s) /2) >= (# of 2s).
Square is always at least 2x2 big.
So for the input (first two numbers are height and width):
6 8
0 0 2 2 2 1 2 1
0 1 2 2 1 0 1 1
0 0 1 0 1 2 0 2
2 1 0 2 2 1 1 1
1 2 1 0 0 0 1 0
1 2 0 1 1 2 1 1
The correct answer is 9.(square is 5x5 big and the upperleft corner is on second row, third column)
Now i managed to somewhat write a program that does this correctly, but it's too slow.
So my I'm asking for an advice how to write the algorithm so that it solves this: https://justpaste.it/1cfem under 1 second(correct answer 15) and this: https://justpaste.it/1cfen under 4 seconds(correct answer 556).
EDIT: I forgot to mention by square I mean only the perimeter of the square (the four sides)
My code works something like this:
Iterate trough all the fields in the input and iterate trough all the possible squares that start in this field(starting from the biggest square possible). Then I have some conditions like that I break the iteration when the possible perimeter of the square is smaller than the already biggest number of 1s i have found so far in a perimete etc. Also when I'm trying to find the squares starting from the given field, I remember the up side and left side of the preceding square and then just decrement it(if there is a 1 or 2).
But this isn't enough, since solution like this solves the second input in like 1 and a half minute a I need it in four seconds.
The code:
NOTE: the minerals represent 1s and toxics represent 2s
#include <stdio.h>
#include <stdlib.h>
int maxMinerals;
void traverseforH(const int const *map, const int height, const int width) {
const int h1 = height - 1;
const int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = width;
int maxBoundm = width;
if (startY + maxBoundm - height - startX > 0) {
maxBoundl = height;
maxBoundm = height;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startY - startX;
maxBoundl = maxBoundm;
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
int upsideData [2];
upsideData[0] = mineralsUpSide;
upsideData[1] = toxicsUpSide;
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
int finalMinerals = lastMinerals + mineralsLeftSide + mineralsUpSide;
int finalToxics = toxics + toxicsLeftSide + toxicsUpSide;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
void traverseforW(int *map, const int height, const int width) {
int h1 = height - 1;
int w1 = width - 1;
int lineOffset = 0;
for (int startY = 0; startY < h1; startY++) {
int yside = height - startY;
if (!(yside * 2 + (yside - 2)*2 > maxMinerals)) {
break;
}
for (int startX = 0; startX < w1; startX++) {
int xside = width - startX;
if (!(xside * 2 + (xside - 2)*2 > maxMinerals)) {
break;
}
int maxBoundl = height;
int maxBoundm = height;
if (startX + maxBoundl - width - startY > 0) {
maxBoundl = width;
maxBoundm = width;
if (startX - startY > 0) {
maxBoundl = maxBoundl + startY - startX;
} else {
maxBoundm = maxBoundm + startX - startY;
}
} else if (startY - startX > 0) {
maxBoundm = maxBoundm + startX - startY;
} else {
maxBoundl = maxBoundl + startX - startY;
maxBoundm = maxBoundl;
maxBoundl = maxBoundl + startY - startX;
}
int mBw = (maxBoundl - 1) * width;
int toxicsLeftSide = 0;
int mineralsLeftSide = 0;
int toxicsUpSide = 0;
int mineralsUpSide = 0;
int mw;
int lastMinerals = 0;
int toxics = 0;
int sidey = lineOffset + width;
for (int x = startX; x < maxBoundm; x++) {
mw = x + lineOffset;
if (map[mw] == 1) {
mineralsUpSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsUpSide++;
toxics++;
}
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundl - 1; y++) {
mw = startX + sidey;
if (map[mw] == 1) {
mineralsLeftSide++;
lastMinerals++;
} else if (map[mw]) {
toxicsLeftSide++;
toxics++;
}
mw = maxBoundm - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
if (map[startX + mBw] == 1) {
mineralsLeftSide++;
} else if (map[startX + mBw]) {
toxicsLeftSide++;
}
if (!(lastMinerals / 2.0 < toxics) && lastMinerals > maxMinerals) {
maxMinerals = lastMinerals;
}
mBw = mBw - width;
int noOfSquares;
if (xside < yside) {
noOfSquares = xside - 1;
} else {
noOfSquares = yside - 1;
}
for (int k = 1; k < noOfSquares; k++) {
int maxBoundy = maxBoundl - k;
int maxBoundx = maxBoundm - k;
if (!(((maxBoundx - startX)*2 + (maxBoundx - 2 - startX)*2) > maxMinerals)) {
break;
}
sidey = lineOffset + width;
lastMinerals = 0;
toxics = 0;
if (map[maxBoundx + lineOffset] == 1) {
mineralsUpSide--;
} else if (map[maxBoundx + lineOffset]) {
toxicsUpSide--;
}
if (map[startX + mBw + width] == 1) {
mineralsLeftSide--;
} else if (map[startX + mBw + width]) {
toxicsLeftSide--;
}
int finalMinerals = mineralsUpSide + mineralsLeftSide;
int finalToxics = toxicsLeftSide + toxicsUpSide;
for (int x = startX + 1; x < maxBoundx; x++) {
mw = x + mBw;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
}
for (int y = startY + 1; y < maxBoundy - 1; y++) {
mw = maxBoundx - 1 + sidey;
if (map[mw] == 1) {
lastMinerals++;
} else if (map[mw]) {
toxics++;
}
sidey = sidey + width;
}
finalMinerals += lastMinerals;
finalToxics += toxics;
if (!(finalMinerals / 2.0 < finalToxics) && finalMinerals > maxMinerals) {
maxMinerals = finalMinerals;
}
mBw = mBw - width;
}
}
lineOffset = lineOffset + width;
}
printf("%d\n", maxMinerals);
}
int main() {
char hw[14];
FILE * file = fopen("pub01.in", "r");
char c;
int k = 0;
while ((c = fgetc(file)) != '\n') {
hw[k] = c;
k++;
}
int h, w;
sscanf(hw, "%d %d", &h, &w);
int size = h * w;
int* input = malloc(size * sizeof (int) + 1);
k = 0;
while ((c = fgetc(file)) != EOF) {
if (c == '0' || c == '1' || c == '2') {
input[k] = c - '0';
k++;
}
}
input[k] = '\0';
if (h > w) {
traverseforH(input, h, w);
} else {
traverseforW(input, h, w);
}
return 0;
}
Preprocess step:
First pre-process matrix, using prefix sum method all rows and columns so that you will be able to calculate # of 1s and # of 2s in the perimeter of square in O(1).
By now you will have 4 data-structures: rowSumFor1, rowSumFor2, colSumFor1, colSumFor2. For example: rowSumFor1[i][j] would tell us # of 1s in ith row for column indices between 0 and j inclusive.
Time complexity: O(w x h)
Complete Code:
#include<stdio.h>
int min(int a,int b){
return (a<=b)?a:b;
}
int max(int a,int b){
return (a>=b)?a:b;
}
// currently hard-coding dimensions for test purposes
// horizontal sums
int rowSumFor1[600][600];
int rowSumFor2[600][600];
// vertical sums
int colSumFor1[600][600];
int colSumFor2[600][600];
int main(){
int w,h;
scanf("%d %d",&h,&w);
for(int row=1;row <= h;row++)for(int col=1;col <= w;col++){
int temp;
scanf("%d",&temp);
// first add previous sum
rowSumFor1[row][col]=rowSumFor1[row][col - 1];
rowSumFor2[row][col]=rowSumFor2[row][col - 1];
colSumFor1[col][row]=colSumFor1[col][row - 1];
colSumFor2[col][row]=colSumFor2[col][row - 1];
if(temp==1){
rowSumFor1[row][col]++;
colSumFor1[col][row]++;
}
else if(temp==2){
rowSumFor2[row][col]++;
colSumFor2[col][row]++;
}
else{
// do nothing
}
}
int result = 0,rowId,colId,mlength;
for(int len=min(w,h); len > 1 ; len-- ) // iteration on possible lengths
{
for(int row=1;row <= (h - len + 1);row++)for(int col=1;col <= (w - len + 1);col++){ // iteration on all co-ordinates as upper-left corner of our square
// Do calculation here for properties and necessary checking constraints for validity of this square
// Note: not checking trivial conditions like boundary conditions in square, you will have to!!
// Beware of over-counting of corners here, one way to avoid is to select indices such that they don't overcount corners
// 4x4 square example for counting
// aaab
// d b
// d b
// dccc
int topEdge1 = rowSumFor1[row][col + len - 2] - rowSumFor1[row][col - 1];
int bottomEdge1 = rowSumFor1[row + len - 1][col + len - 1] - rowSumFor1[row + len - 1][col];
int leftEdge1 = colSumFor1[col][row + len - 1] - colSumFor1[col][row];
int rightEdge1 = colSumFor1[col + len - 1][row + len - 2] - colSumFor1[col + len - 1][row - 1];
int ones= topEdge1 + bottomEdge1 + leftEdge1 + rightEdge1; // # of 1s on perimeter of this square
int topEdge2 = rowSumFor2[row][col + len - 2] - rowSumFor2[row][col-1];
int bottomEdge2 = rowSumFor2[row+len-1][col+len-1] - rowSumFor2[row+len-1][col];
int leftEdge2 = colSumFor2[col][row + len - 1] - colSumFor2[col][row];
int rightEdge2 = colSumFor2[col + len - 1][row + len - 2] - colSumFor2[col + len -1][row - 1];
int twos= topEdge2 + bottomEdge2 + leftEdge2 + rightEdge2; // # of 2s on perimeter of this square
if(ones >= 2* twos){
if(ones > result){
result = ones;
rowId = row;
colId = col;
mlength = len;
}
}
}
}
printf("%d %d %d\n",rowId,colId,mlength);
printf("%d\n",result);
return 0;
}
Time complexity: O(w x h x min(w,h))
EDIT:
Replaced pseudo-code with complete code. It results as expected for all 3 tests presented by OP.

longest subsequence with alternate signs

Given an array of +ve and -ve integers. Write an algorithm to find longest subsequence with alternate signs.
If 0 is there in array, it can be considered as both +ve and -Ve.
Exampls : Array : 5,-9,4,0,-1,5,-5,3,0,2
Longest subsequence : [0,-1,5,-5,3,0,2] size: 7
I wrote one function, it's working fine , but is there any other better way?
void f (int A[],int N){
int fIndex = 0;
int eIndex = 0;
int maxCount =0;
int curCount =0;
int start =0;
for(int i=1;i<N;++i){
if(A[i] > 0 && A[i-1]>=0){
if(i>=2 && A[i-2] < 0){
fIndex = i;
curCount =0;
}
}
if(A[i] < 0 && A[i-1] <=0){
if(i>=2 && A[i-2] > 0){
fIndex = i;
curCount =0;
}
}
if((A[i] > 0 && A[i-1] <= 0) || (A[i] <0 && A[i-1]>=0)){
curCount++;
if(curCount > maxCount){
maxCount = curCount;
}
start = fIndex;
eIndex = i;
}else if(A[i] == 0){
if(A[i-1]> 0){
A[i] = -1;
}
curCount++;
if(curCount > maxCount){
maxCount = curCount;
}
eIndex = i;
}
}
return maxCount+1;
}
There are only two possibilities for alternation like -+-+... or +-+-.... so we can just use two counters and reset them when a number comes we don't like:
int max = 0;
int[] l = {0, 0};
for (int i = 0; i < N; i++) {
if (a[i] == 0) {
l[0]++;
l[1]++;
continue;
}
int s = ((i % 2 == 0 && a[i] < 0) || (i % 2 == 1 && a[i] > 0)) ? 0 : 1;
l[1-s]++;
if (l[s] > max)
max = l[s];
l[s] = 0;
}
return max >= l[0] && max >= l[1] ? max : (l[0] >= l[1] ? l[0] : l[1]);

Resources