Search algorithm optimization - java

The code "works", but I'm having problems with optimization.
Algorithms idea is count the number of ways you can navigate n × n grid starting from the top left corner, always moving one step to the left, right, up or down, visiting each square. For example, when n = 3, there are 8 possible paths.
For example the algorithm gets unbearably slow with p.count(7), any hints/tips?
public class Paths {
static int[][] grid;
static int n,counter;
public int count(int n) {
grid = new int[n][n];
counter = 0;
search(0,0,1,n);
return counter;
}
void search(int y, int x, int k, int n) {
if (y < 0 || x < 0 || y >= n || x >= n) return;
if (grid[y][x] != 0) return;
if (x-1 > 0 && x+1 < n && y == n && grid[y][x-1] == 0 && grid[y][x+1] == 0) return;
else if (x-1 > 0 && x+1 < n && y == 0 && grid[y][x-1] == 0 && grid[y][x+1] == 0) return;
else if (y-1 > 0 && y+1 < n && x == n && grid[y-1][x] == 0 && grid[y+1][x] == 0) return;
else if (y-1 > 0 && y+1 < n && x == 0 && grid[y-1][x] == 0 && grid[y+1][x] == 0) return;
else if (y==n && x==n && grid[y][x-1] == 0 && grid[y-1][x] == 0) return;
else if (y==n && x==0 && grid[y-1][x] == 0 && grid[y][x+1] == 0) return;
else if (y==0 && x==n && grid[y+1][x] == 0 && grid[y][x-1] == 0) return;
if (k == n*n) {
counter++;
return;
}
grid[y][x] = k;
search(y,x-1,k+1,n);
search(y,x+1,k+1,n);
search(y+1,x,k+1,n);
search(y-1,x,k+1,n);
grid[y][x] = 0;
}
}
Output:
public static void main(String[] args) {
Paths p = new Paths();
System.out.println(p.count(1)); // 1
System.out.println(p.count(2)); // 2
System.out.println(p.count(3)); // 8
System.out.println(p.count(4)); // 52
}
}

Related

How to convert for loop into streams?

How would I use streams to achieve the same result as below? I am trying to find the average of this 'tot' value by first iterating through TickQueue (a queue implementation) and summing tot, and then afterwards dividing by the counter value to find the average.
int counter = 0;
double tot = 0;
for (Tick t: TickQueue)
{
if ((t.getAskPrice() == 0 && t.getBidPrice() == 0) || (t.getAskPrice() == 0) || (t.getBidPrice() == 0))
{
tot += 0;
}
else
{
tot += (t.getAskPrice() - t.getBidPrice());
counter++;
}
}
double avg = tot/counter;
Use a DoubleStream for sum/average/count:
double avg = tickQueue.stream()
.filter(t -> t.getAskPrice() != 0 && t.getBidPrice() != 0)
.mapToDouble(t -> t.getAskPrice() - t.getBidPrice())
.average()
.orElse(0.0);
TickQueue.stream().
filter(t -> !((t.getAskPrice() == 0 && t.getBidPrice() == 0) || (t.getAskPrice() == 0) || (t.getBidPrice() == 0)).
forEach(t -> {
tot += (t.getAskPrice() - t.getBidPrice());
counter++;
});
You first filter out the values where ((t.getAskPrice() == 0 && t.getBidPrice() == 0) || (t.getAskPrice() == 0) || (t.getBidPrice() == 0)), and then for the remaining values calculate tot and counter.

Why doesn't this code work? FizzBuzz JAVA

I cant get "FizzBuzz". No matter what the input, the "FizzBuzz" code isn't running. What did I do wrong?
public String[] fizzBuzz(int start, int end) {
int diff = end-start;
String[] array = new String[diff];
for (int i = 0; i < diff; i++) {
if (start%3 == 0 && start%5 == 0) array[i] = "FizzBuzz";
if (start%3 == 0 || start%5 == 0) {
if (start%3 == 0) array[i] = "Fizz";
if (start%5 == 0) array[i] = "Buzz";
}
else {
array[i] = String.valueOf(start);
}
start++;
}
return array;
}
Logic in your if statements is a bit busted, using your code as the starting point, you'd have to do something like this.
if (start%3 == 0 && start%5 == 0) {
array[i] = "FizzBuzz";
}
else if (start%3 == 0 || start%5 == 0) {
if (start%3 == 0) array[i] = "Fizz";
if (start%5 == 0) array[i] = "Buzz";
}
else {
array[i] = String.valueOf(start);
}
String s = "" + i;
if ((i % 3) == 0) {
s += " Fizz";
}
if ((i % 5) == 0) {
s+= " Buzz";
}
System.out.println(s);
This code snippet placed in a loop will print Fizz, Buzz and Fizz Buzz on i divisible by 3, 5 and 15 respectively.
you should try this.
class FizzBuzz{
public static void main(String args[]){
int n = 100;
for(int i=0;i<=n;i++){
if((i % 3) == 0 && (i % 5) != 0){
System.out.println("Fizz");
}
else if((i % 5) == 0 && (i % 3) != 0){
System.out.println("Buzz");
}else if((i % 3) == 0 && (i % 5) == 0){
System.out.println("FizzBuzz");
}else{
System.out.println(""+i);
}
}
}
}

Error message "Operator '&&' cannot be applied to 'int' 'boolean'

public class LargestEven {
public int largestEven(int x, int y, int z) {
if(x % 2 = 0 && x > y && x > z) {
return x;
} else if (y % 2 = 0 && y > x && y > z) {
return y;
} else if (z % 2 = 0 && z > x && z > y) {
return z;
} else {
return 0;
}
}
public static void main(String[] args) {
LargestEven l = new LargestEven();
System.out.println(l.largestEven(1, 3, 5)); //prints 0
System.out.println(l.largestEven(2, 4, 9)); //prints 4
System.out.println(l.largestEven(2, 1001, 1003)); //prints 2
}
}
I have to make a program that finds the largest even number out of 3 given numbers. However I can't seem to get it to work because I keep getting this error message. What exactly am I doing wrong here?
Sorry for the beginner question, but I've never seen this error message before and have no idea what it means or how to fix it.
Thank you in advance.
You have to use == to compare & use = for assignment
if (x % 2 == 0 && x > y && x > z) {
return x;
} else if (y % 2 == 0 && y > x && y > z) {
return y;
} else if (z % 2 == 0 && z > x && z > y) {
return z;
} else {
return 0;
}
You have to check even and odd condition of individual as well as in group for each condition and then check for largest and return.
public int largestEven(int x, int y, int z) {
if (x % 2 == 0 && (y%2!=0 && z%2!=0)) {
return x;
}else if(y%2==0 && (x%2!=0 && z%2!=0) ){
return y;
}else if(z%2==0 && (x%2!=0 && y%2!=0) ){
return z;
}else if(x%2==0 && y%2==0 && z%2!=0){
return x>y?x:y;
}else if(x%2==0 && z%2==0 && y%2!=0){
return x>z?x:z;
}else if(y%2==0 && z%2==0 && x%2!=0){
return y>z?y:z;
}else if(x%2==0 && y%2==0 && z%2==0 ){
return x > y ? (x > z ? x : z) : (y > z ? y : z) ;
}else{
return 0;
}
}
public static void main(String[] args) {
System.out.println(largestEven(6, 3, 4)); //prints 6
System.out.println(largestEven(2, 4, 8)); //prints 8
System.out.println(largestEven(2, 1006, 1003)); //prints 1006
}
In your if and else if statements you have the following lines:
x % 2 = 0
Try changing it to this
x % 2 == 0 // Multiple ==
The single = is used to assign values, like this:
int i = 0;
And two == is used for compares like in your if and else if:
if (i == 0){
...
}
The statement inside the if is an boolean. This would do exactly the same, but assigning it to a boolean first:
boolean x = (i == 0);
if (x){ // OR if (x == true){
...
}
I hope the difference is clear now. I also suggest looking a bit more into the basics of Java or programming in general.
You have used assignment operator = in your conditions instead of == equality operator. Please follow the logic below. I have also given a optimized version of it.
When you are looking at x then make sure other variable (y,z) are not divisible by 2 and if they do then they are less then x. Then replicate the same for other conditions.
public int largestEven(int x, int y, int z) {
if(x % 2 == 0 && ((y % 2 != 0) || (y%2 == 0 && y < x)) && ((z % 2 != 0) || (z % 2 == 0 && z < x))) {
return x;
} else if (y % 2 == 0 && ((x % 2 != 0) || (x%2 == 0 && x < y)) && ((z % 2 != 0) || (z % 2 == 0 && z < y))) {
return y;
} else if (z % 2 == 0 && ((x % 2 != 0) || (x%2 == 0 && x < z)) && ((y % 2 != 0) || (y % 2 == 0 && y < z))) {
return z;
} else {
return 0;
}
}
You can further optimize the conditions check using the information you have gained in your previous checks.
public int largestEven(int x, int y, int z) {
if(x % 2 == 0 && ((y % 2 != 0) || (y%2 == 0 && y < x)) && ((z % 2 != 0) || (z % 2 == 0 && z < x))) {
return x;
} else if (y % 2 == 0 && ((z % 2 != 0) || (z % 2 == 0 && z < y))) {
return y;
} else if (z % 2 == 0) {
return z;
} else {
return 0;
}
}
Once comparing for x when we come to y then we need to worry about x. because it can not be higher y and divisible by 2 so we can remove that from condition. similarly for z.

How can I get this program to print out ten items per line seperated by 1 space?

Here's my code so far
public class DivisibleBy5and6
{
public static void main (String []args)
{
for (int i = 100; i <= 200; i++)
{
boolean num = (i % 5 == 0 || i % 6 == 0) && !(i % 5 == 0 && i % 6 == 0);
if (num == true)
System.out.println(i + " is divisible");
}
}
}
Like stated previously how can I get the output to print out 10 items per line separated by a space?
How about:
int count = 0;
for (int i = 100; i <= 200; i++) {
boolean num = (i % 5 == 0 || i % 6 == 0) && !(i % 5 == 0 && i % 6 == 0);
if (num == true) {
count++;
System.out.print(i + " is divisible ");
if(count >= 10) {
System.out.println();
count -= 10;
}
}
}

Maze recursion - going wrong for few inputs (likely error in the logic)

I am a beginner in java.
I have been working on an maze problem trying it solve it by recursion.
I have written the code which seems to work on few inputs and not others.
The input is a maze consisting of 0's and 1's. # is the start and # is the exit.0 is wall and 1's are open.The output will be the hops from # to #.
Though i am solving the problem by recursion,I must be going wrong with the logic.
Please let me know where I am wrong.
Class practisenumwords
import java.util.Scanner;
class practisenumwords {
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int r=in.nextInt();
int c=in.nextInt();
maze maz=new maze(r,c); /*input in string copied to array*/
char[] ch;
ch = "00000000111111101111011001101##11100".toCharArray();
int l=0;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++) /*initialising the maze elements*/
{
maz.m[i][j]=new cells();
maz.m[i][j].c=ch[l];
maz.m[i][j].row=i;
maz.m[i][j].col=j;
l++;
}
}
for(int i=0;i<r;i++) /*print the input maze */
{
for(int j=0;j<c;j++)
{
System.out.print(""+maz.m[i][j].c);
}
System.out.println();
}
maz.escape();
maz.find(maz.startx,maz.starty,maz.hops);
}
}
Class cells
class cells {
char c;
int row;
int col;
boolean done=false; /*initially all cells are unvisited*/
}
Class maze
class maze{
maze (int a,int b){
rows=a;
cols=b;
m=new cells[rows][cols];
}
int rows;
int cols;
cells[][] m;
int startx,starty;
int hops=0;
void escape()
{
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
if(m[i][j].c=='#')
{
startx=i;
starty=j;
System.out.println(startx+" "+starty);
}
}
}
}
void find(int x,int y,int h)
{
if ((x+1<rows && m[x+1][y].c=='#' && m[x+1][y].done!=true)
||(x-1>=0 && m[x-1][y].c=='#' && m[x-1][y].done!=true)
||(y+1<cols && m[x][y+1].c=='#' && m[x][y+1].done!=true)
||(y-1>=0 && m[x][y-1].c=='#' && m[x][y-1].done!=true)){
h++;
System.out.println(h);
}
else
{
if(x-1>=0 && m[x-1][y].c=='1' && m[x-1][y].done!=true){ /*north cell*/
m[x][y].done=true;
h++;
find(x-1,y,h);
}
if(x+1<rows && m[x+1][y].c=='1' && m[x+1][y].done!=true){ /*south cell*/
m[x][y].done=true;
h++;
find(x+1,y,h);
}
if(y+1<cols && m[x][y+1].c=='1' && m[x][y+1].done!=true){ /*east cell*/
m[x][y].done=true;
h++;
find(x,y+1,h);
}
if(y-1>=0 && m[x][y-1].c=='1' && m[x][y-1].done!=true){ /*west cell*/
m[x][y].done=true;
h++;
find(x,y-1,h);
}
}
}
}
Now,i get the right output for the inputs as the 1 in program.
000000
001111
111011
110110
01101#
#11100
output- 12 (obtaining right output)
00#000
001111
111011
110110
011011
#11100
output- 7 (obtaining right output)
BUT NOT FOR OTHER INPUTS like
0 0 0 0 # 0
0 1 0 1 1 0
1 1 1 1 0 1
0 1 0 1 0 0
0 0 # 1 1 1
0 1 1 0 0 1
correct output - 6 output obtained -7
Also the output changes with the order in which the adjacent cells are checked.
Honestly, I'd implement your recursive function a little differently:
And there's no need to check whether a bool value is != true, !boolValue is fine.
int find(int x,int y,int h)
{
int result = -1;
if ((x+1<rows && m[x+1][y].c=='#' && !m[x+1][y].done)
||(x-1>=0 && m[x-1][y].c=='#' && !m[x-1][y].done)
||(y+1<cols && m[x][y+1].c=='#' && !m[x][y+1].done)
||(y-1>=0 && m[x][y-1].c=='#' && !m[x][y-1].done)){
return h + 1;
}
else
{
if(x-1>=0 && m[x-1][y].c=='1' && !m[x-1][y].done){ /*north cell*/
m[x][y].done=true;
result = find(x-1,y,h + 1)
if (result > -1) {
return result;
}
m[x][y].done=false;
}
Implement the other three directions the same way, then result should still be -1 if no solution was found.
return result;
}
In a fast reading I notice:
if(...) {
...
h++;
find(x-1,y,h);
}
For each if-block.
Inside second if-block h == h+2 when first if-condition is satisfied and the same goes for third and fourth if-block
Maybe you should write:
if(...) {
...
// h++;
find(x-1,y,h+1);
}
int find(int x, int y, int h) {
if ((x + 1 < rows && m[x + 1][y].c == '#' && m[x + 1][y].done != true)
|| (x - 1 >= 0 && m[x - 1][y].c == '#' && m[x - 1][y].done != true)
|| (y + 1 < cols && m[x][y + 1].c == '#' && m[x][y + 1].done != true)
|| (y - 1 >= 0 && m[x][y - 1].c == '#' && m[x][y - 1].done != true)) {
h++;
finish = true;
return h;
} else {
if (x - 1 >= 0 && m[x - 1][y].c == '1' && m[x - 1][y].done != true
&& !finish) { /* north cell */
m[x][y].done = true;
int temp = find(x - 1, y, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (x + 1 < rows && m[x + 1][y].c == '1'
&& m[x + 1][y].done != true && !finish) { /* south cell */
m[x][y].done = true;
int temp = find(x + 1, y, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (y + 1 < cols && m[x][y + 1].c == '1'
&& m[x][y + 1].done != true && !finish) { /* east cell */
m[x][y].done = true;
int temp = find(x, y + 1, h);
if (temp != 0)
h = temp + 1;
return h;
}
if (y - 1 >= 0 && m[x][y - 1].c == '1' && m[x][y - 1].done != true
&& !finish) { /* west cell */
m[x][y].done = true;
int temp = find(x, y - 1, h);
if (temp != 0) {
h = temp + 1;
}
return h;
}
return 0;
}
}
Also include a boolean finish = false; in your maze class.
and also change the return of the main function
maz.hops = maz.find(maz.startx, maz.starty, maz.hops);
System.out.println(maz.hops);

Categories