I'm looking for an explanation on the following problem
Given an input - array of integers such as 1 2 3 4 I want to produce all of the possible "permutations" which look like this0 0 0 1 , 0 0 0 2, first one goes like this until 0 0 0 4 , next one looks like this 0 0 1 0 and then 0 0 1 1 .I hope you got my point.I have already constructed an iterative algorithm which produces the series but it uses too much memory for an input of size 10, the solution I'm looking for doesn't use recursion. Please note that there are (n + 1)! (0,0,0,0 included) possiblities.
The input is limited to integers and it is always the case that the count of values generated equals the count of the input values.
EDIT
Please note that there might be such a solution here in Stackoverflow but I can't really define a proper name for the problem that's why if anyone has any clue on how to actually name this problem,please do share!
Thanks!
To generate your series you basically do this:
Start with an array containing only zeroes, of the correct length
Iterate, and for each iteration do "basic math" like incrementation of the number, as though each element of the array is a single digit of a larger number.
Basically increment the last number by 1
If this ends up being higher than the max for that position, reset it to 0 and move on to the digit to the left
If it didn't end up being higher than the max, you got a new solution
When the move-on-to-the-digit-to-the-left operation falls off the left end of the array, you're done
Here is a LINQPad solution that demonstrates:
void Main()
{
CountedPermutations(1, 2, 3)
.Select(l => new { a = l[0], b = l[1], c = l[2] })
.Dump();
}
public static IEnumerable<int[]> CountedPermutations(params int[] maxValues)
{
int[] results = new int[maxValues.Length];
yield return results; // the all-zeroes solution
while (true)
{
// Increment to next solution
if (CountedPermutationsMutate(results, maxValues))
{
// make a copy of the array and yield return it
// we make copies so that if the outside code puts everything in a
// collection, we don't just end up with N references to the same array
// with the same values.
yield return results.ToArray();
}
else
break;
}
}
public static bool CountedPermutationsMutate(int[] values, int[] maxValues)
{
int index = values.Length - 1;
bool gotSolution;
while (true)
{
if (values[index] < maxValues[index])
{
// won't overflow this position, so we got a new solution
values[index]++;
gotSolution = true;
break;
}
else
{
// Overflow in this position, reset to 0
// and move on to the next digit to the left
values[index] = 0;
index--;
// If we fell off the left end of the array, we're done
if (index < 0)
{
gotSolution = false;
break;
}
}
}
return gotSolution;
}
This will output:
0 0 0
0 0 1
0 0 2
0 0 3
0 1 0
0 1 1
0 1 2
0 1 3
0 2 0
0 2 1
0 2 2
0 2 3
1 0 0
1 0 1
1 0 2
1 0 3
1 1 0
1 1 1
1 1 2
1 1 3
1 2 0
1 2 1
1 2 2
1 2 3
Consider using iterators to avoid storing of every generated value.
Related
So let's say that I have an array of zeroes, where the number 1 occasionally occurs.
For example, let's say I have the following array:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0
The output I am trying to get is the following descriptions about the positions of the number 1:
Every 5th starting with 2
Every 11th starting with 3
Every 7th starting with 0
We can see that if we start with an array of zeroes:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Then we add a 1 every 5th number starting with 2:
0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
Then we add a 1 every 11th number starting with 3:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0
Then we add a 1 every 7th number starting with 0:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0
We get the array that we started out with.
One obvious thing is that there is more than one set of instructions that result in this array. For example, instead of the third instruction Every 7th starting with 0, we could have stated the instruction Every 21st starting with 0, or Every 1000000th starting with 21. Therefore, an obvious solution for this problem is to find each location of 1, and make each instruction Every [large number]th starting with [a certain position of 1].
However, I am looking for an algorithm that can find the most optimal, or close to the most optimal, set of instructions that gives the locations of the 1's in the array.
Based on its applications and input, the discrete Fourier transform looks promising; however, since it gives a pair of numbers for each value in the array, this doesn't seem very efficient.
So, are there any algorithms out there (perhaps in the Fourier family?) that can help me do this?
Thank you!
EDIT - for clarification, I don't care about the length of the array. Feel free to pad it with zeroes to the nearest power of two, or anything else.
EDIT 2 - if needed, feel free to make a rule of removing a 1. For instance, Remove every 6th starting with 4 would also work.
The following program uses rules that have a start and an end. The rules are allowed to overlap, so that a 1 could be used in 2 or more rules. It would be very easy to modify the code if that isn't what you want.
If the number of 1s is small it should be very fast, but it won't scale well.
It isn't very "clever". All it does is aim to knock out as many ones at each stage as possible. This approach is not optimal but it should be very good in most cases. For example, if you start with
1 1 1 1 1 0 1 1 1 1 1
the first rule found is
Every 2th, starting at 1, ending at 11.
because it uses six ones. However, the best solution clearly needs only two rules involving five 1s. I think it would be very difficult to find an efficient algorithm that always finds the best answer.
public static void main(String[] args) {
rulesFor(0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0);
}
public static void rulesFor(int... arr) {
Set<Integer> allOnes = new HashSet<>();
for (int i = 0; i < arr.length; i++)
if (arr[i] == 1)
allOnes.add(i);
// Size 1 has to be done separately as the below code wouldn't work.
if (allOnes.size() == 1) {
int a = allOnes.iterator().next();
System.out.println("Every 1st, starting at " + (a + 1) + ", ending at " + (a + 1) + ".");
return;
}
Set<Integer> leftToRemove = new HashSet<>(allOnes);
while (!leftToRemove.isEmpty()) {
int low = -1;
int high = -1;
int d = -1;
int removeTotal = -1;
for (int a : leftToRemove) {
for (int b : allOnes) {
if (b == a)
continue;
int d2 = Math.abs(b - a);
int low2 = a;
int high2 = a;
int removeTotal2 = 1;
while (true) {
if (!allOnes.contains(low2 - d2))
break;
low2 -= d2;
if (leftToRemove.contains(low2))
removeTotal2++;
}
while (true) {
if (!allOnes.contains(high2 + d2))
break;
high2 += d2;
if (leftToRemove.contains(high2))
removeTotal2++;
}
if (removeTotal2 > removeTotal) {
low = low2;
high = high2;
removeTotal = removeTotal2;
d = d2;
}
}
}
System.out.println("Every " + d + "th, starting at " + (low + 1) + ", ending at " + (high + 1) + ".");
for (int i = low; i <= high; i += d)
leftToRemove.remove(i);
}
}
I have a file with some values in it:
11
8
0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0 0
0 0 1 1 1 1 1 1 1 0 0
0 1 1 0 1 1 1 0 1 1 0
1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 0 1
1 0 1 0 0 0 0 0 1 0 1
0 0 0 1 1 0 1 1 0 0 0
I need to read those values into a 2D ArrayList. The fist two values (11 and 8) would be the number of rows and columns respectively. So here is the code:
Scanner scanner = new Scanner(file);
int x, y;
x = scanner.nextInt();
System.out.println(x + " has been read");
y = scanner.nextInt();
System.out.println(y + " has been read");
ArrayList<ArrayList<Boolean>> pixelMap;
pixelMap = new ArrayList<ArrayList<Boolean>>();
ArrayList<Boolean> buffer_line = new ArrayList<Boolean>();
Boolean buffer;
for (int i = 0; i < x; i++){
for (int j = 0; j < y; j++){
buffer = scanner.nextBoolean();
System.out.println(buffer + " has been read");
//buffer_line.add(buffer);
}
//pixelMap.add(buffer_line);
//buffer_line.clear();
}
The problem is - the program reads first two numbers successfully, and when it comes to boolean values, it throws InputMismatch exception on line
buffer = scanner.nextBoolean();
so I can't undersand why. 0 should be read next and it is boolean - so what's actually mismatching?
I also point out that if change buffer type to integer and then assign scanner.nextInt(), the program would read all the values properly, so in the output I would see all of them. So then of course, I can change ArrayList to Integer to make that work, but it would be semantically wrong as it would hold only boolean values.
Can anyone help me to find out the problem?
In your code you have this statement:
buffer = scanner.nextBoolean();
But I do not see boolean values true or false in the input file.
In Java, 0 and 1 are not treated as boolean values like in other languages such as C.
You need to read these values as int and then manually map them to boolean values.
Logic something like this:
int val = scanner.nextInt();
boolean buffer = (val == 1) ? true : false;
I'm trying to create a basic RTS style grid. The grid works perfectly and I can place object by setting a number to anything other than 0.
That's the easy part. currently im trying to allow each object that is placed to be rotated. The objects that can be rotated can be any size e.g. 1x1, 2x1, 3x4 etc, and all object have an entry block which needs to be rotated with the object.
For example.
My grid is empty
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
and I can place an object shown below:
1 2 1
1 1 1
which will place like
0 0 0 0 0 0 0
0 1 2 1 0 0 0 1 2 1
0 1 1 1 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
but when rotated it should place like
1 2 1 0 1 1 0 1 2 1 1 1
1 1 1 0 1 2 0 1 1 1 1 2
0 0 0 0 1 1 0 1 1
0 1 1 0 0 0 0 1 1
0 2 1 0 1 1 1 2 1 1 1 1
0 1 1 0 1 2 1 1 1 1 2 1
Im trying to figure out how this could be acheived in code considering that the object can be of different shapes? :(
1 1 2 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 2 1 1 1 1 1
1 1 1 1 1 1
I figured out how to accomplish this from another board on here.
First thing I did was store the object in a 2 dimensional array e.g.
1 2 1 1
1 1 1 1
I then transposed the array leaving me with this array
1 1
2 1
1 1
1 1
And then I rotated each row leaving me with my final rotated object
1 1
1 2
1 1
1 1
And for 180+ rotations I just use this technique again to reach the desired rotation :)
My final Array Class in Unity3D C#
using UnityEngine;
using System.Collections;
namespace Arrays {
public class Array {
public static int[,] Rotate(int[,] array)
{
return Rotate90 (array);
}
public static int[,] Rotate90(int[,] array)
{
return RotateArrayRow( Transpose(array) );
}
public static int[,] Rotate180(int[,] array)
{
return Rotate90(Rotate90(array));;
}
public static int[,] Rotate270(int[,] array)
{
return Rotate90(Rotate180(array));;
}
private static int[,] RotateArrayRow(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[y,x];
for(int i=0; i<y; i++)
{
for(int j=0; j<x; j++)
{
temp[i,x-j-1] = array[i,j];
}
}
return temp;
}
public static int[,] Transpose(int[,] array){
int x = array.GetLength(1);
int y = array.GetLength(0);
int[,] temp = new int[x,y];
for(int i=0; i<y;i++){
for(int j=0; j<x; j++){
temp[j,i] = array[i,j];
}
}
return temp;
}
public static void Log(int[,] array){
for(int i=0; i<array.GetLength(0); i++)
{
string line = "";
for(int j=0; j<array.GetLength(1); j++)
{
line += array[i,j] + " ";
}
Debug.Log(line);
}
}
}
}
One thing to think about first is that to rotate your objects you only need to implement one rotation function: 90 degrees in one direction. The other rotations just repeat this operation 2 or 3 times, simplifying your logic.
There are two mappings from original to rotated array you need to consider:
How do the dimensions map?
How do the indices map?
1 is easy: the dimensions are swapped. A rotated 1x4 becomes 4x1.
2 depends on your implementation, but if you're using 2d coordinates [x, y] => [y, -x] or [-y, x] depending on direction of rotation.
I'm stuck trying to create a 3 x 2 matrix that only contains 0 and 1 and prints out all the possible combinations, BUT it can only contain one 1 and one 0 for each row, the numbers have nothing to do with each other than that they are unique, much like a betting table for say tennis or something:
0 1 1 0 0 1 0 1 0 1
0 1 1 0 0 1 1 0 1 0
0 1 1 0 1 0 1 0 0 1
Here's the code:
public class Program {
public static void main(String[] args) {
int[][] array = {{0,1}};
System.out.println("Array:");
for(int row = 0; row < array.length; row++){
for(int column = 0; column < array[row].length; column++){
System.out.print(array[row][column] + " ");
}
System.out.println();
}
}
}
This is what I got right know. I don't know where to take it from here.
For a general case of an N-by-2 matrix there will be 2^N combinations that meet your criteria. Consider that each row can only be in two states: [0, 1], or [1, 0].
Start with a matrix where every row is in the initial state [0, 1]. Then, for every number X where 0 <= X < 2^N, convert X to binary. When the Mth bit is 1, reverse the Mth row's values.
For example, binary 000 would correspond to:
0 1
0 1
0 1
While binary 101 would correspond to:
1 0 (swapped)
0 1
1 0 (swapped)
I have 2D array for example like this:
1 1 1 0 0
0 0 1 1 1
1 0 1 0 1
0 0 0 1 1
0 0 0 0 1
Now if I choose random position for example position [4, 2], I would like to get array like this:
X X X X X
0 0 X X X
X 0 X 0 X
0 0 0 X X
0 0 0 0 X
Any ideas for this algorithm? No matter in which language. I just need the algorithm.
I think you are looking for a flood fill algorithm here. So, given a point, you need to check left, top, right and bottom and the diagonals and if they are of the same value, recurse (or put it into the queue)
public void fill(int i, int j, int value) {
if(checkSameValue(i, j, value) {
mark(i, j);
} else {
return;
}
if(insideBounds(i, j-1, value)) {
fill(i, j-1, value);
}
//Similarly for top, right and bottom and diagonals
}
Implement using a queue to prevent StackOverFlow errors. BTW this is just an implementation of the flood fill algorithm, you need to modify it a tiny bit for your case. Don't want to deprive you of all the fun :)