In a recent interview I had, they asked me this question:
Consider a battlefield to be made up of square cells of unit dimensions. A soldier on the battlefield can move from a cell to all(8) of it's neighboring cells. soldier has a gun with him which he can shoot the targets up to any distance along any of the 8 possible directions (north,east,west,south,north-east,north-west,south-east,south-west). also some cells are bulletproof which prevents bullets to pass but soldier can walk over them as if it were a normal cell.he can destroy the target from a bulletproof cell but not from a cell behind it.
Given the position of the target, starting position of a target and position of all the bullet proof cells. you have to tell the position of closest shooting point i.e the cell from which, the soldier can shoot the target and is closest to the starting position of the soldier. if there are more than one such cells, output all of them.
Input specifications :
I) size of the battlefield { integer pair (N,M) : battlefield will be of N*M size )
II) starting position of the soldier {integer pair (i,j)}
III) position of the target {integer pair (x,y) : position of the cell on which target is mounted}
IV) position of all the bullet proof cells { list of integer pair a#b : each element in the list is a position of a bullet proof cell}*
Output specifications :
Sequential list of integer pair i#j (cell) that are closest shoot points and must follow row wise traversal.
Note: if the output list contains four shoot points : (2,1), (1,2), (3,2), (2,4) on a 4x4 battle field.
then the correct output will be {1#2,2#1,2#4,3#2} not {1#2,2#1,3#2,2#4}
Example: Input : {2,2} {2,1} {2,2} {1#1,1#2} Output : 2#1
My Code:
public class Test2 {
public static void main(String[] args) {
int[] size = {4, 4};
int[] startPt = {1, 1};
int[] endPt = {4, 2};
String[] impenetrable = {"2#2", "3#3","3#2"};
Process(size, startPt, endPt, impenetrable);
}
public static void Process(int[] size, int[] startPt, int[] endPt, String[] impenStr) {
//Initialize starting position.
int x = startPt[0] - 1;
int y = startPt[1] - 1;
List<String> output = new ArrayList<String>();
int count = 0;
int[][] direction = {{x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}};
int[][] board = new int[size[0]][size[1]];
board[startPt[0] - 1][startPt[1] - 1] = 1;
board[endPt[0] - 1][endPt[1] - 1] = 2;
//Impenetrable Points
for (String p : impenStr) {
String[] tmp = p.split("#");
board[Integer.parseInt(tmp[0]) - 1][Integer.parseInt(tmp[1]) - 1] = 99;
}
System.out.println("The Board:");
for (int m = 0; m < board.length; m++) {
for (int n = 0; n < board.length; n++) {
System.out.print(board[m][n] + "\t");
}
System.out.println();
}
while (output.isEmpty()) {
output = Surroundings(direction, endPt[0], endPt[1], board);
//for (int m = 0; m < board.length; m++) {
// for (int n = 0; n < board.length; n++) {
// if(m!=startPt[0] - 1 || n!=startPt[1] - 1){
// }
//}
//}
direction[0][0] = direction[0][0] - 1; // up
direction[0][1] = direction[0][1];
direction[1][0] = direction[1][0] + 1; // Down
direction[1][1] = direction[1][1];
direction[2][0] = direction[2][0]; // Left
direction[2][1] = direction[2][1] - 1;
direction[3][0] = direction[3][0]; // right
direction[3][1] = direction[3][1] + 1;
direction[4][0] = direction[4][0] - 1; // NE
direction[4][1] = direction[4][1] + 1;
direction[5][0] = direction[5][0] + 1; // SW
direction[5][1] = direction[5][1] - 1;
direction[6][0] = direction[6][0] + 1; // SE
direction[6][1] = direction[6][1] + 1;
direction[7][0] = direction[7][0] - 1; // NW
direction[7][1] = direction[7][1] - 1;
count++;
if (!output.isEmpty()) {
break;
}
}
System.out.println(Arrays.toString(output.toArray()));
}
public static List<String> Surroundings(int[][] direction, int targetX, int targetY, int[][] board) {
String string = "";
List<String> output = new ArrayList<String>();
for (int i = 0; i < direction.length; i++) {
try {
if (board[direction[i][0]][direction[i][1]] == 99) {
board[direction[i][0]][direction[i][1]] = 0;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
if (checkDirections(board, direction[i][0], direction[i][1], targetX - 1, targetY - 1) == true) {
string = string + (direction[i][0] + 1) + "#" + (direction[i][1] + 1);
}
try {
if (board[direction[i][0]][direction[i][1]] == 0) {
board[direction[i][0]][direction[i][1]] = 99;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
if (!string.equals("")) {
output.add(string);
string = "";
}
}
return output;
}
public static boolean checkDirections(int[][] battleField, int x, int y, int finalX, int finalY) {
return North(battleField, x, y, finalX, finalY) == true
|| South(battleField, x, y, finalX, finalY) == true
|| West(battleField, x, y, finalX, finalY) == true
|| East(battleField, x, y, finalX, finalY) == true
|| NE(battleField, x, y, finalX, finalY) == true
|| SE(battleField, x, y, finalX, finalY) == true
|| NW(battleField, x, y, finalX, finalY) == true
|| SW(battleField, x, y, finalX, finalY) == true;
}
public static boolean North(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return North(board, x - 1, y, targetX, targetY);
}
}
public static boolean South(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return South(board, x + 1, y, targetX, targetY);
}
}
public static boolean West(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return West(board, x, y + 1, targetX, targetY);
}
}
public static boolean East(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return East(board, x, y - 1, targetX, targetY);
}
}
public static boolean NE(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return NE(board, x - 1, y + 1, targetX, targetY);
}
}
public static boolean SW(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return SW(board, x + 1, y - 1, targetX, targetY);
}
}
public static boolean SE(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return SE(board, x + 1, y + 1, targetX, targetY);
}
}
public static boolean NW(int[][] board, int x, int y, int targetX, int targetY) {
if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
return false;
} else if (x == targetX && y == targetY) {
return true;
} else {
return NW(board, x - 1, y - 1, targetX, targetY);
}
}}
Where I got stuck:
Consider this image to be the battlefield and the yellow block to be the starting point.
In my code, for each loop, I go on searching through the elements of the outer ring.
I get the correct solution for all the blocks horizontally, vertically and diagonally.(Blue Blocks in the image).
But I am unable to access the red blocks. How do I access them too?
Currently your main method has a fixed number (8) of cells that it is checking at each step. This isn't going to work as each 'step' outwards actually increases the number of cells you should be checking by 8.
Given the number of cells you are checking is pretty small the simplest solution is probably to just check every cell on the board rather than stepping outwards. You can maintain a variable with the minimum distance to the target as you go.
The code would look something like this:
int minDistanceToTarget = Integer.MAX_VALUE;
for each position on the board
if position can hit target
if distance < minDistanceToTarget
minDistanceToTarget = distance
output = ""
if distance == minDistanceToTarget
add position to output
Hopefully you see how that works: it reset the output whenever it finds a closer position that can hit the target and then adds all positions at that distance to the output.
As an aside, I think your code would be a lot neater if you encapsulated your positions in a Position class rather than storing as a second dimension in your array. Something like:
enum Direction {
N, NE, E, SE, S, SW, W, NW;
public int getRowDelta();
public int getColDelta();
}
class Position
private final int row;
private final int col;
public Position(int row, int col);
public int distanceTo(Position other);
public Position move(Direction direction);
}
class Board {
private final int width;
private final int height;
private final Position start;
private final Position target;
private final List<Position> bulletproofCells;
public Board(String input);
public String getOutput();
}
You will find you can remove the duplication of code in methods if you encapsulate logic in classes such as these.
Write a program that reads integers from the user until he enters -1, and print “Consecutive ” if there are three consecutive numbers otherwise print “None Consecutive”; that is in the number list you read are in an order such that there is some integer k that the numbers values are k, k+1, and k+2.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int y = x + 1;
int z = x + 2;
boolean areConsecutive = false;
while (x != -1) {
if (x == y) {
x = scan.nextInt();
if (x == z)
areConsecutive = true;
}
x = scan.nextInt();
}
if (areConsecutive)
System.out.print("Consecutive");
else
System.out.print("None Consecutive");
}
Can anyone please tell me what's wrong with this code?
Get the next integer before checking with y, then check for z. if one of these fails update y and z and check again.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int y = x + 1;
int z = x + 2;
boolean areConsecutive = false;
while (x != -1) {
x = scan.nextInt();
if (x == y) {
x = scan.nextInt();
if (x == z)
areConsecutive = true;
}
y = x + 1;
z = x + 2;
}
if (areConsecutive)
System.out.print("Consecutive");
else
System.out.print("None Consecutive");
}
You need to increment y and z by 1 before scaning new x.
This is what you are looking for:
Scanner scan = new Scanner(System.in);
System.out.println("enter");
int x = scan.nextInt();
boolean areConsecutive = false;
while (x != -1) {
int y = x + 1;
System.out.println("enter");
x = scan.nextInt();
if (x == y) {
System.out.println("enter");
int z = x + 1;
x = scan.nextInt();
if (x == z)
areConsecutive = true;
}
}
if (areConsecutive)
System.out.println("Consecutive");
else
System.out.println("None Consecutive");
You're close but you're not maintaining the history of the numbers correctly.
First, to clarify, the specification calls for you to enter an arbitrary quantity of arbitrary numbers from the user and simply check if any three of them are consecutive. Hence the first line below would have a consecutive sequence (the 1 2 3 bit starting at the third number) but the second would not:
9 9 1 2 3 9
3 1 4 1 5 9
One way to do this is simply maintain the minimal information to detect a consecutive sequence. To do that, you need to keep a copy of only the last three numbers entered. The pseudo-code (easily transformable into any procedural language) for such a beast would be:
# Get first number, ensure no chance of consecutive
# sequence until at least three are entered.
num3 = getint()
num2 = num3
num1 = num3
consecutive = false
# Loop until -1 entered.
while num3 != -1:
# Check for consecutive sequence.
if (num1 + 1 == num2) and (num2 + 1 == num3):
consecutive = true
# Shift numbers "left".
num1 = num2
num2 = num3
num3 = getint()
if consecutive:
print "Consecutive"
else
print "None Consecutive"
This is what you are looking for:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int y = scan.nextInt();
int z = scan.nextInt();
boolean areConsecutive = false;
while ((x != -1)&&(y != -1)&&(z != -1)){
if ((z == y + 1)&&(y == x + 1)
areConsecutive = true;
if (areConsecutive)
System.out.print("Consecutive");
else
System.out.print("None Consecutive");
}
I would do it this way, we have to check if three numbers are consecutive no matter the order they were entered by user:
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int[] numbers = new int[3];
for( int i = 0; i < numbers.length; ++i)
numbers[i] = scan.nextInt();
Arrays.sort(numbers);
boolean areConsecutive = true;
for( int i = 0; i < numbers.length - 1; ++i)
if(numbers[i+1] - numbers[i] != 1)
areConsecutive = false;
if(areConsecutive)
System.out.print("Consecutive");
else
System.out.print("None Consecutive");
}
Diophantine reciprocals III
In the following equation x, y, and n are positive integers.
1/x + 1/y = 1/n
For a limit L we define F(L) as the number of solutions which satisfy x < y ≤ L.
We can verify that F(15) = 4 and F(1000) = 1069.
Find F(10^12).
The equation is equivalent to z = xy/(x + y). Let d = gcd(x, y). Then
x = dm, y = dn, with gcd(m, n) = 1.
It follows that gcd(mn, m + n) = 1 so that
z = dmn / (m + n),
which implies (m + n) | d, i.e., d = k(m + n), k a positive integer.
Thus we obtain the solutions:
x = km(m + n), y = kn(m + n), z = kmn,
where the three parameters k, m, n are positive integers.
For I/p=15 I am getting o/p=4 & for I/p=1000 I am getting o/p=1069 in 18sec but for I/p=10^12 no o/p is being displayed. How to handle such huge I/p?
public class testClient {
public static void main(String[] args) {
System.out.println(diophantineReciprocals(1000.0));
}
private static double diophantineReciprocals(double L) {
double noOfSolutions = 0;
double d = 1;
double m = 1;
double n = 1;
double z = 0;
for (double x = 1; x < L; x++) {
for (double y = x + 1; y <= L; y++) {
d = gcd(x, y);
m = x / d;
n = y / d;
x = d * m;
y = d * n;
z = m * n * d / (m + n);
if (/* z == (x * y) / (x + y) && */Math.round(z) != 0
&& (z - Math.round(z)) == 0) {
noOfSolutions++;
}
}
}
return noOfSolutions;
}
private static double gcd(double x, double y) {
double gcd = 1;
for (double i = 2; i <= x; i++) {
if (x % i == 0 && y % i == 0) {
if (i > gcd) {
gcd = i;
}
}
}
return gcd;
}
}
I must write a program in java (homework) that gives the input (x), the input in binary, tells if the input is a palindrome and tells if the binary from the input is a palindrome. I may not use api's other than System.out.print and I may not use strings.
So far so good: I've written the program and it works till x = 1023 (because of the int). Which piece of code must I edit, so the input can be any positive number?
class Palindromes {
public static int DtoBinary(int x) {
int y = x;
int w = 1;
int v = 0;
int z = 1;
int u = 0;
while (z < y) {
z = z * 2;
u++;
}
z = z / 2;
for (int t=1; t<u; t++) {
w = 10 * w;
}
v = v + w;
y = y - z;
while (y > 0) {
z = z / 2;
if (z <= y) {
w = w / 10;
v = v + w;
y = y - z;
} else if (y == 1) {
v = v + 1;
y = 0;
} else {
w = w / 10;
v = v + 0;
}
}
return v;
}
public static boolean Palindrome(int x) {
int s = x;
int r = 0;
while (s > 0) {
int q = s % 10;
r = r * 10 + q;
s = s / 10;
}
if (x == r) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
int x = 1023;
System.out.print(x + " " + DtoBinary(x));
if (Palindrome(x)) {
System.out.print(" yes");
} else {
System.out.print(" no");
}
if (Palindrome(DtoBinary(x))) {
System.out.print(" yes");
} else {
System.out.print(" no");
}
}
}
You can use a char array instead of an int to store large binary numbers for your palindrome class.
public static char[] DtoBinary(int x) {
<insert code to convert x to an array of zeroes and ones>
}
You will need to write a method that checks if a char array is a palindrome.
I can offer short solution for homework.
public static boolean isPalindrome(int x) {
String inputted = "" + x;
String reverse = new StringBuffer(inputted).reverse().toString();
return inputted.equals(reverse);
}
or
public static boolean isPalindrome(int x) {
String inputted = "" + x;
int length = inputted.length;
for(int i = 0; i< inputted/2; i++){
if(inputted.charAt(i)!= inputted.charAt(inputted - 1 - i)){
return false;
}
}
return true;
}
I tried Binary multiplication technique on decimal numbers.
Algorithm:
To multiply two decimal numbers x and y, write them next to each
other, as in the example below. Then repeat the following: divide the first number by 2,
rounding down the result (that is, dropping the :5 if the number was odd), and double the
second number. Keep going till the first number gets down to 1. Then strike out all the rows
in which the first number is even, and add up whatever remains in the second column.
11 13
5 26
2 52
1 104
........
143 (answer)
Code:
class Multiply
{
static int temp;
static int sum;
public static void main(String[] args)
{
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
int ans = multiply(x , y);
System.out.println(ans);
}
public static int multiply(int x, int y)
{
if(x==1)
{
System.out.println(x+" : "+y);
return y;
}
temp = multiply(x/2, y*2);
if(x%2==0)
{
System.out.println(x+" : "+y);
return temp;
}
else
{
System.out.println(x+" : "+y);
sum = sum+temp;
return sum;
}
}
}
Something is wrong with the recursion i think but i couldn't find what it is!!
When having recursion do not use variables outside the recursive method. It is too confusing. I mean that the recursive method should be self-contained. Here is a working version of your program:
public class Main {
public static void main(String[] args) {
int x = 11;
int y = 13;
int ans = multiply(x, y);
System.out.println(ans);
}
public static int multiply(int x, int y) {
if (x == 1) {
return y;
}
int temp = multiply(x / 2, y * 2);
if (x % 2 != 0) {
temp += y;
}
return temp;
}
}
Your recursion should be like this -
public class Multiply {
static int temp = 0;
static int sum = 0;
public static void main(String[] args) {
int x = Integer.parseInt("11");
int y = Integer.parseInt("9");
int ans = multiply(x, y);
System.out.println(ans);
}
public static int multiply(int x, int y) {
if (x == 1) {
System.out.println(x + " : " + y);
return sum + y;
}
if (x % 2 == 0) {
System.out.println(x + " : " + y);
} else {
System.out.println(x + " : " + y);
sum = sum + y;
}
return multiply(x / 2, y * 2);
}
}
I couldn't resist to post it in a single line
public static int multiply(int x, int y) {
return ((x & 1) > 0 ? y : 0) + ((x & ~1) > 0 ? multiply(x >> 1, y << 1) : 0);
}
I couldn't resist to add an iterative solution: fast, simple and valid
also for negative arguments:
int product(int x, int y) {
boolean positive = x >= 0;
int p = 0;
while (x != 0) {
if (x % 2 != 0) p += y;
x /= 2;
y *= 2;
}
return positive ? p : -p;
}
Here is simple Java implementation which does multiplication without multiplication operator.
public static int multiply(int a, int b) {
int p = 0;
// If a is odd number.
if ((a & 1) > 0) {
p = b;
} //else use the default value in the p.
// If 'a' contains any number larger than one
// than continue recursion.
if (a > 1)
p = p + multiply(a >> 1, b << 1);
return p;
}
public static int multiply(int x, int y) {
if (y == 0 || x == 0) {
return 0;
}
if (x == 1) {
return y;
} else {
return multiply(x >> 1, y << 1);
}
}