I'm sure there is a CS term for what I'm trying to accomplish but I'm not sure what it is. I have three arrays, let's call them a, b, and c. I am iterating through every possible combination of the arrays, which would be a*b*c iterations.
I am passing a function an int of the current iteration (such that iteration goes from 0 to a*b*c-1) and the length of a, b, and c. I want that function to be able to print out every unique permutation of indices, calculated from just the iteration count and the lengths of a, b, and c.
This is what I have now:
class Test {
public static void printIndices(int i, int a, int b, int c) {
System.out.println(i%a + ", " + (i+1)%b + ", " + (i+2)%c);
}
public static void main(String[] args) {
int a[] = new int[2];
int b[] = new int[2];
int c[] = new int[3];
int iterations = a.length * b.length * c.length;
for (int i=0; i < iterations; i++){
printIndices(i, a.length, b.length, c.length);
}
}
}
It generates this output:
0, 1, 2
1, 0, 0
0, 1, 1
1, 0, 2
0, 1, 0
1, 0, 1
0, 1, 2
1, 0, 0
0, 1, 1
1, 0, 2
0, 1, 0
1, 0, 1
As you can see there are duplicates. I want the output to be:
0, 0, 0
1, 0, 0
0, 1, 0
1, 1, 0
0, 0, 1
1, 0, 1
0, 1, 1
1, 1, 1
0, 0, 2
1, 0, 2
0, 1, 2
1, 1, 2
(the order is unimportant, as long as every permutation is there with no duplicates).
Obviously my output line is wrong:
System.out.println(i%a + ", " + (i+1)%b + ", " + (i+2)%c);
What are the correct operations to get the output I am looking for?
I understand that this code is a bit silly looking and it's not at all what I'm actually doing, but it demonstrates the case well.
As mentioned in the comments you are looking for the Cartesian product.
Your approach with modular arithmetic almost works. You need only a few modifications to get the correct result:
System.out.println(i%a + ", " + (i/a)%b + ", " + (i/a/b)%c);
See it working online: ideone
Related
I am writing a small program to take an input array, nums and create a new array that is double the size and returns the last number from the previous array as the last and only different number in the new array.
When I try to return this number using the nums.length - 1 formula to get the end of the array, it returns the number in the middle of the new array. Below is my program.
public int[] makeLast(int[] nums) {
int lengonewarr = nums.length;
int officiallength = lengonewarr * 2;
int [] makezero = new int [officiallength];
makezero [nums.length-1] = nums[nums.length-1];
return(makezero);
}
These are the outputs I should be making:
makeLast([4, 5, 6]) → [0, 0, 0, 0, 0, 6]
makeLast([1, 2]) → [0, 0, 0, 2]
makeLast([3]) → [0, 3]
But I instead get something like:
makeLast([1, 2, 3, 4]) → [0, 0, 0, 0, 0, 0, 0, 4] (My output) [0, 0, 0, 4, 0, 0, 0, 0]
makeLast([2, 4]) → [0, 0, 0, 4] (My output) [0, 4, 0, 0]
Any advice is greatly appreciated.
the array makezero's length is officiallength, not nums.length, just replace the first nums.length by makezero.length or officiallength.
makezero [makezero.length -1] = nums[nums.length-1];
BTW: It's better to name the variable with camelCase style, which will make the code more readable. Like makeZero or officialLength
I modified your and here it is:
public int[] makeLast(int[] nums) {
int lengonewarr = nums.length;
int officiallength = lengonewarr * 2;
int [] makezero = new int [officiallength];
makezero [makezero.length-1] = nums[nums.length-1];
return(makezero);
}
As the array makezero is double size, the length of lengonewarr is always in the middle of makezero.
public static boolean isSplitable(int[] arr, int diff, int i)
no loops or helper methods i need to check if arr[i...arr.length - 1] has a two section sum that is equal to diff
for example i have: diff = 1, i = 2, arr = {3, 4, 1, 1, 2, 0, 1, 1, 3} it returns true because sum of {1, 1, 2, 0}(4) minus the sum of {1, 1, 3}(5) equals diff(1).
i have tried to think of ways to even sum arr without a loop only thing i came up with is adding it to diff but then i lose my original diff plus i dont know the amount of elements so i can add "or" in my return statement so now im out of ideas.
I'm assuming your restrictions are no loops and no library usage. You probably need some kind of additional functions. Moreover, I assume the difference check shall use absolute values, i.e. it does not matter if the first or second sum is smaller, as long as the difference matches (-1 or 1 in your example). That being said, a first approach could look like this:
import org.junit.jupiter.api.Test;
import static java.util.Arrays.copyOfRange;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RecursiveSplitTest {
#Test
public void testIsSplitable() {
{
int[] array = {3, 4, 1, 1, 2, 0, 1, 1, 3};
assertTrue(isSplitable(array, 1, 2));
}
{
int[] array = {3, 4, 1, 1, 1, 0, 4, 1, 3};
assertTrue(isSplitable(array, 1, 4));
}
{
int[] array = {3, 4, 1, 1, 1, 0, 4, 1, 3};
assertFalse(isSplitable(array, 1, 7));
}
{
int[] array = {3};
assertFalse(isSplitable(array, 1, 1));
}
}
public static boolean isSplitable(int[] array, int diff, int start) {
if (start < 0 || start > array.length - 2) {
System.out.println("Not possible due to initial parameters");
return false;
}
return doSplitableRecursive(copyOfRange(array, start, array.length), diff, 0);
}
private static boolean doSplitableRecursive(int[] array, int diff, int start) {
if (start + 1 >= array.length) {
System.out.println("Could not find it");
return false;
}
int[] left = copyOfRange(array, 0, start + 1);
int[] right = copyOfRange(array, start + 1, array.length);
int leftSum = sum(left, 0);
int rightSum = sum(right, 0);
System.out.println("leftSum: " + leftSum);
System.out.println("rightSum: " + rightSum);
if (leftSum + diff == rightSum || leftSum - diff == rightSum) {
System.out.println("Found match for cut at start + " + (start + 1));
return true;
}
return doSplitableRecursive(array, diff, start + 1);
}
private static int sum(int[] array, int current) {
if (array.length == 0) {
return current;
}
return sum(copyOfRange(array, 1, array.length), current + array[0]);
}
}
The key is to systematically divide the array in two pieces, beginning at start and checking the sum of each piece against the difference. Then cutting one index further and repeating the process if it did not match. Finally, you have to exit with false if there are no more elements left.
It is a little rough around the edges. Feel free to improve it and fix possibly remaining bugs. The print statements are for debugging purposes. Of course, one could argue JUnit and java.util.Arrays are library functions. These can be replaced with a little bit of extra effort if needed.
Just get my hand on coding and it is very addicted. So I try new challenge in making puzzle solver. I am getting so close to finish it but get stuck.
There are 2 main methods: puzzleSolver and check
I have tested check method with all cases and it is working very well.
So the only problem is solve method and I dont know whats wrong with it.
Please look at my code and help me out.
Very appreciate.
I will explain the rules below.
RULES:
1.No 3 consecutive values (1 and 2) in each row and column.
2.Each row and column contains the same amount of values.
If grid[6][6]. Each row and column will have 3 of 1s and 3 of 2s.
But cannot have 3 of 1s or 2s next each other.
Example:
grid[2][2]
0 1
1 0
Solution:
2 1
1 2
grid[2][2]
1 1
0 0
Unsolvable
It violated rule number 2.
grid[4][4]
[0, 2, 2, 1]
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
solution:
[1, 2, 2, 1]
[1, 2, 1, 2]
[2, 1, 2, 1]
[2, 1, 1, 2]
grid[4][4]
[0, 2, 2, 2] <- violated rule number 2
[0, 2, 1, 2]
[2, 1, 0, 1]
[2, 0, 0, 0]
Unsolvable
grid[6][6]
[0, 0, 1, 1, 1, 0] <- violated rule #1
[0, 0, 0, 1, 0, 0]
[2, 2, 2, 0, 0, 0] <-violated rule #1
[0, 0, 0, 1, 0, 0]
[0, 1, 2, 0, 0, 0]
[0, 2, 0, 1, 0, 0]
Unsolvable
This is my input grid:
public static void main(String[] args) {
int[][] grid = { { 0, 1 }, { 1, 0 } };
int[][] grid1 = { { 0, 2, 2, 1 }, { 0, 2, 1, 2 }, { 2, 1, 0, 1 }, { 2, 0, 0, 0 } };
int[][] grid2 = { { 0, 2, 2, 0 }, { 0, 0, 0, 0 }, { 0, 2, 0, 0 }, { 0, 0, 0, 1 } };
int[][] grid3 = { { 0, 0, 1, 0, 2, 2 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 2, 0, 0 },
{ 2, 0, 1, 0, 0, 0 }, { 0, 0, 2, 1, 2, 0 } };
It works in some cases but not all and I dont know why
OUTPUT
Fail to find solution
[0, 2, 2, 0]
[0, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 0, 1]
false
Solution should have:
1, 2, 2, 1
2, 1, 1, 2
1, 2, 1, 2
2, 1, 2, 1
Here is my code
Solve method will run all row and column and uses check method to decide which value to be placed
public static boolean puzzleSolve(int[][] grid) {
for (int row = 0; row < grid.length; row++) {
// column start from 0 and increasing as going down
for (int col = 0; col < grid.length; col++) {
// start at 0, 0
if (grid[row][col] == 0) { // if value =0, will be replaced with n
for (int n = 1; n < 3; n++) { // n =1 or n=2
grid[row][col] = n; // place n=1 then check condition
if (check(grid)) {
grid[row][col] = n;// if true, replace 0 with n
if (solve(grid)) { // check whole grid if violated rules
return true;
}
}
}
// System.out.println("No solution");
return false; // fail in replacing
}
}
}
// print out solved grid if succeed
System.out.println("solution: ");
for (int i = 0; i < grid.length; i++) {
System.out.println(Arrays.toString(grid[i]));
}
return true; // success
}
//end code
I have check method to detect any violations and it work well in any cases.
I know there is something wrong in solve method but cannot find it.
In, pseudocode, your solution reads like:
for each cell with value zero
for each allowed value
place value in cell
check if it's a solution
Walkthrough what happens if you have all zeroes in you cells. The first cell will be given value 1, then 2, neither of which solve the whole grid (because there are still zeroes). So it moves the second cell and so on throughout the grid, leaving each cell with value 2. It obviously won't find a solution in that situation.
Your first issue here is that you actually aren't doing any recursion or backtracking.
A correct solution will likely look like:
solve (grid, position):
if position is past end and grid is solved
yah!
else
for each allowed value
place value in position on grid
call solve(grid, next position)
That's recursive (because it calls itself) and backtracking because if it can't find a solution it returns to a previous position (above it in the call stack) and tries a new value.
So an actual solution might look something like:
private void findSolutions(int[][] grid, int col, int row) {
if (row == grid.length && isSolved(grid)) {
printSolution(grid);
} else {
for (int v = 1; v <= 2; v++) {
grid[row][col] = v;
if (col == grid[row].length) {
findSolutions(grid, 0, row + 1);
} else {
findSolutions(grid, col + 1, row + 1);
}
}
}
}
Writing a code that shifts array elements left by an int n (keyboard input) and replaces space with zeros.
Ex. int[] data = { -1, 1, 3, 7, 5} and I want to see { 3, 7, 5, 0, 0}.
Suppose I have:
public static void shiftLeft( int[] data, int n )
{
System.arraycopy( data, 1, data, 0, data.length - 1 );
data[data.length - 1] = 0;
}
Any quick help would be great.
You were close, but your srcPos argument should be n and the length argument should be data.length - n. You can then use the overloaded Arrays#fill method that accepts a start/end index to fill the rest of the array with 0:
public static void shiftLeft(int[] data, int n) {
System.arraycopy(data, n, data, 0, data.length - n);
Arrays.fill(data, data.length - n, data.length, 0);
}
Testing this with your example input yields the following:
int[] data = { -1, 1, 3, 7, 5};
shiftLeft(data, 2);
System.out.println(Arrays.toString(data));
Output:
[3, 7, 5, 0, 0]
I am having a problem programming the below problem in java it is a constraint satisfaction problem:
If I have constraints like this:
x1 + x2 > x3
x2 - x4 = 2
x1 + x4 < x5
Each of x1 to x5 are in the domain {0,1,2}
How do I program the different combinations such that I will have a set of tuples as: {(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0), ......} for each constraint
that is constraint 1 for instant has domain of tuple such as {(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0),(0,1,2),(2,0,1) ......}
I need the reply in any language but preferably java please.
You could perhaps do this through the use of some helper methods from the google commons collect library. It would look something like this:
I'm assuming that the tuples (0,0,0) etc are tuples of the input to the constraint, (x0, x1, x2) for constraint1, (x2, x4) for constraint2 etc.
So, for constraint1, first we fill a list with all possible combinations:
final List<int[]> allCombos = new ArrayList<int[]>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
allCombos.add(new int[] {i, j, k});
}
}
}
for (final int[] i : allCombos) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
Next, we want to filter so we'll be left with the tuples that are allowed by constraint1:
final List<int[]> constraint1 = ImmutableList.copyOf(Iterables.filter(allCombos, new Predicate<int[]>() {
#Override
public boolean apply(#Nullable final int[] input) {
return input[0] + input[1] > input[2];
}
}));
for (final int[] i : constraint1) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
This might need a little explanation.
ImmutableList.copyOf is a method that creates a copy of a given list. To this method, we pass the result of Iterables.filter(), which takes a list (the input to be filtered), and a Predicate, which has an overridden method apply(), where you decide which element of the input list that are supposed to be part of the result list. Here, we basically just code the constraint itself, and the cases where the apply method returns true will be part of the filtered list. (I've chosen to represent the tuples as an array, you could use the filter-strategy with any tuple-representation..)
The result of the last printouts (the filtered list) will be:
0, 1, 0
0, 2, 0
0, 2, 1
1, 0, 0
1, 1, 0
1, 1, 1
1, 2, 0
1, 2, 1
1, 2, 2
2, 0, 0
2, 0, 1
2, 1, 0
2, 1, 1
2, 1, 2
2, 2, 0
2, 2, 1
2, 2, 2
I'll leave it up to you to do the same for the other constraints..