Nested For Loop and specific array element searching - java

I have a question on the method and process of how to look at these generated arrays.
Basically I want to create an array of [a,b,c,(a+b+c)] and as well as a second array of [d,e,f,(d+e+f)] and if the third element in array1 and array2 are the same, display the arrays to strings.
int num = 10;
for(int a = 0; a < num; a++){
for(int b = 0; b < num; b++){
for(int c = 0; c < num; c++){
if(a<=b && b<=c){
arrayOne[0] = a;
arrayOne[1] = b;
arrayOne[2] = c;
arrayOne[3] = (a+b+c);
}
}
}
}
for(int d = 0; d < num; e++){
for(int e = 0; e < num; e++){
for(int f = 0; f < num; f++){
if(d<=e && e<=f){
arrayTwo[0] = d;
arrayTwo[1] = e;
arrayTwo[2] = f;
arrayTwo[3] = (f -(d+e));
}
}
}
}
as you can see I am beyond stump.I am not quite sure where i can get each iteration of the arrays and compare the values by matching the sums in each array and as well as displaying the respective array they are in. Thank you all in advanced.

If I understand your question correctly if a=1, b=3, c=4 and d=2, e=3, f=3 you'd like to print something along the lines of 1 + 3 + 4 = 8 = 2 + 3 + 3. First, what you're doing right now is creating two arrays like Floris described in the comment. What you want to do is store all the values in one array of arrays, as follows:
int max; \\ To determine the value of max see the edit below.
int array[][] = new int[max][num];
int index = 0;
for (int a=0; a < num; a++) {
for (int b=a; b < num; b++) {
for (int c=b; c < num; c++) {
array[index][0] = a;
array[index][1] = b;
array[index][2] = c;
array[index][3] = a + b + c;
index++;
}
}
}
for (int i = 0; i < max; i++) {
for (int j = i; j < max; j++) {
if (array[i][3] == array[j][3]) {
string outString = array[i][0] + " + " + array[i][1] + " + " + array[i][2] + " = " + array[i][3] + " = " + array[j][0] + " + " + array[j][1] + " + " + array[i][2];
System.out.println(outString);
}
}
}
You can see that I improved performance by starting b from a and c from b since you are throw out all the values where b < a or c < b. This also should eliminate the need for your if statement (I say should only because I haven't tested this). I needed to use an independent index due to the complexities of the triple nested loop.
Edit 2: Ignore me. I did the combinatorics wrong. Let An,k be the number of unordered sets of length k having elements in [n] (this will achieve what you desire). Then An,k = An-1,k + An,k-1. We know that An,1 = n (since the values are 0, 1, 2, 3, 4, ..., n), and A1,n = 1 (since the only value can be 11111...1 n times). In this case we are interested in n= num and k = 3 , so plugging in the values we get
A_num,3 = A_num-1,3 + A_num,2
Apply the equation recursively until you come to an answer. For example, if num is 5:
A_5,3 = A_4,3 + A_5,2
= A_3,3 + A_4,2 + A_4,2 + A_5,1
= A_3,3 + 2(A_4,2) + 5
= A_2,3 + A_3,2 + 2(A_3,2) + 2(A_4,1) + 5
= A_2,3 + 3(A_3,2) + 2(4) + 5
= A_1,3 + A_2,2 + 3(A_2,2) + 3(A_3,1) + 2(4) + 5
= 1 + 4(A_2,2) + 3(3) + 2(4) + 5
= 1 + 4(A_1,2) + 4(A_2,1) + 3(3) + 2(4) + 5
= 1 + 4(1) + 4(2) + 3(3) + 2(4) + 5
= 5(1) + 4(2) + 3(3) + 2(4) + 5
It looks like this may simplify to (num + (num - 1)(2) + (num - 2)(3) + ... + (2)(num - 1) + num) which is binomial(num, num) but I haven't done the work to say for sure.

int givenNumber = 10;
int []arrayOne = new int [4];
int []arrayTwo = new int [4];
int count = 0;
for ( int i = 0; i < givenNumber; i ++)
{
for ( int x = 0; x < givenNumber; x ++ )
{
for ( int a = 0; a < givenNumber; a++ ){
arrayOne[0] = (int)(a * java.lang.Math.random() + x);
arrayOne[1] = (int)(a * java.lang.Math.random() + x);
arrayOne[2] = (int)(a * java.lang.Math.random() + x);
arrayOne[3] = (int)(arrayOne[0]+arrayOne[1]+arrayOne[2]);
}
for ( int b = 0; b < givenNumber; b++ ){
arrayTwo[0] = (int)(b * java.lang.Math.random() + x);
arrayTwo[1] = (int)(b * java.lang.Math.random() + x);
arrayTwo[2] = (int)(b * java.lang.Math.random() + x);
arrayTwo[3] = (int)(arrayTwo[0]+arrayTwo[1]+arrayTwo[2]);
}
if (arrayOne[3] == arrayTwo[3])
{
for ( int a = 0; a < 2; a++ )
{
System.out.print(arrayOne[a] + " + ");
} System.out.print(arrayOne[2] + " = " + arrayOne[3] + " = ");
for ( int a = 0; a < 2; a++ )
{
System.out.print(arrayTwo[a] + " + ");
} System.out.print(arrayTwo[2]);
System.out.println("\n");
count += 1;
}
}
}
if (count == 0)
System.out.println(
"\nOops! you dont have a match...\n" +
"Please try running the program again.\n");

Related

Why the baby step giant step algorithm does not work

I've been sitting for 3 days, I checked through debugging, I still don't see an error.
An equation like this: y = a^x mod p
To get started, we choose m=k=sqrt(p) + 1
. Then we start laying out 2 rows:
First: (a,ay,a^2 * y....a^(m-1) * y) mod p.
Second: (a^m, a^2m...a^km) mod p.
Then we look for the first available value from row 1 in the second and write down the indices of both, the answer should be
x = im - j, the equality a^(im) = a^j * y must also hold
BigInteger p = new BigInteger("61");
BigInteger m = p.sqrt().add(BigInteger.ONE);
BigInteger k = p.sqrt().add(BigInteger.ONE);
BigInteger a = new BigInteger("2");
BigInteger y = new BigInteger("45");
ArrayList<BigInteger> array1 = new ArrayList<>();
ArrayList<BigInteger> array2 = new ArrayList<>();
for(BigInteger i = BigInteger.ZERO; i.compareTo(m) < 0; i = i.add(BigInteger.ONE)) {
BigInteger temp = y.multiply(a.pow(i.intValue())).mod(p);
System.out.println(temp);
array1.add(temp);
}
System.out.println("---------------------------------------------------------");
System.out.println("---------------------------------------------------------");
System.out.println("---------------------------------------------------------");
for(BigInteger j = BigInteger.ONE; j.compareTo(k) < 0; j = j.add(BigInteger.ONE)) {
BigInteger temp = a.pow(j.multiply(m).intValue()).mod(p);
array2.add(temp);
System.out.println("temp = " + temp);
for(int h = 0; h < array1.size(); h++) {
if(Objects.equals(array1.get(h), temp)) {
System.out.println(a.pow(m.multiply(BigInteger.valueOf(h)).intValue()));
System.out.println(a.pow(j.intValue()).multiply(y));
System.out.println("h = " + h + " m = " + m + " j = " + j);
return BigInteger.valueOf(h).multiply(m).subtract(j);
}
/*if(a.pow(m.multiply(BigInteger.valueOf(h)).intValue()).equals(a.pow(j.intValue()).multiply(y))) {
System.out.println("h = " + h + " m = " + m + " j = " + j);
return new BigInteger("-1");
}*/
}
}
return new BigInteger("-1");
}

Find duplicated elements in a matrix

Introduction
I'm doing some homework where we are tasked for making a game of finding pairs.
I made a matrix and filled it with letters as such:
Display
----------------
C H F E
G F D D
E C H B
A B G A
Right now I'm currently testing the display method which uses an empty matrix and fills it with the given input (row_1, col_1, row_2, col_2, gameMatrix)
Problem
While creating a "cheat/test function" to test my display method. I encounter some trouble with finding the position of both A's (or any other letter).
This is my try at such method:
Code
public static void PlayMeBoi(String[][] gameMatrix)
{
int row_1 = 0;
int col_1 = 0;
int row_2 = 0;
int col_2 = 0;
for (int i = 0; i < gameMatrix.length; i++)
{
for (int j = 0; j < gameMatrix.length; j++)
{
if ("A".equals(gameMatrix[i][j]))
{
row_1 = i;
col_1 = j;
break;
}
}
}
for (int i = (row_1+1); i < gameMatrix.length; i++)
{
for (int j = (col_1+1); j < gameMatrix.length; j++)
{
if ("A".equals(gameMatrix[i][j]))
{
row_2 = i;
col_2 = j;
break;
}
}
}
System.out.println("First " + gameMatrix[row_1][col_1] + " at " + " [ " + row_1 + " ] " + "," + " [ " + col_1 + " ] ");
System.out.println("Second " + gameMatrix[row_1][col_1] + " at " + " [ " + row_2 + " ] " + "," + " [ " + col_2 + " ] ");
Turn(row_1, col_1, row_2, col_2, gameMatrix);
}
Notes about the code
I'm working with String not char
Turn is the function which evaluates if a letter equals a letter (if "A".equals("A"))
The (row_1+1) and (col_1+1) it's my thought at "if I haven't found my letter previously, then the second 'for' will handle the rest of the matrix)
gameMatrix is the matrix where all the letters are loaded
Question
I want to be able to find the position of both "A" or any other letter inside the matrix. As of now, I'm not getting my desired result with my current idea
Feel free to comment about the code as much as you can. I might post it on GitHub later on for those who are interested or find anything useful in it.
Thanks for the interest in this question.
The second for is wrong. let's look at your example matrix:
C H F E
G F D D
E C H B
A B G A
If you're looking for the value D you'll find it first at row = 1 and col = 2. then in the second for you only runs from row = 2 and col = 3 which means in practice you'll iterate only over the right down cells from the position you found, which in this example will result in only 2 cells instead of 9 (marked in *):
C H F E
G F D D
E C H *B*
A B G *A*
So in the second for what you should do is continue the search from the same row and the next column:
for (int i = row_1; i < gameMatrix.length; i++)
{
// In the first row starting from the next cell, in the next rows start
// from column 0
int j = i == row_1 ? col_1 + 1 : 0;
for (; j < gameMatrix.length; j++)
{
if ("A".equals(gameMatrix[i][j]))
{
row_2 = i;
col_2 = j;
break;
}
}
}
if I haven't found my letter previously, then the second 'for' will
handle the rest of the matrix
Correct, but what exactly is the rest of the matrix?
If the 1st A is found in row = 1 and col = 1, is the rest of the matrix every item with indices > 1. This would leave out items with indices (1,2) and (2,1) and (1,3) etc.
There are other issues also.
When you put a break inside a nested loop it only breaks form the nested loop and not the outer.
Here's a solution I came up with, maybe it's not optimal but I think it works:
public static void PlayMeBoi(String[][] gameMatrix) {
int row_1 = -1;
int col_1 = -1;
int row_2 = -1;
int col_2 = -1;
boolean found = false;
for (int i = 0; i < gameMatrix.length; i++) {
if (found) break;
for (int j = 0; j < gameMatrix[0].length; j++) {
if ("A".equals(gameMatrix[i][j])) {
row_1 = i;
col_1 = j;
found = true;
break;
}
}
}
if (!found) {
System.out.println("Not Found");
return;
}
found = false;
for (int i = 1; i < gameMatrix.length; i++) {
if (found) break;
for (int j = 1; j < gameMatrix[0].length; j++) {
if (i * gameMatrix[0].length + j > row_1 * gameMatrix[0].length + col_1) {
if ("A".equals(gameMatrix[i][j])) {
row_2 = i;
col_2 = j;
found = true;
break;
}
}
}
}
System.out.println("First " + gameMatrix[row_1][col_1] + " at " + " [ " + row_1 + " ] " + "," + " [ " + col_1 + " ] ");
if (!found) {
System.out.println("Second Not Found");
return;
}
System.out.println("Second " + gameMatrix[row_1][col_1] + " at " + " [ " + row_2 + " ] " + "," + " [ " + col_2 + " ] ");
}

Trying to get my algorithm to O(n) runtime

So in my advanced algorithms class, we are to write an algorithm for a program to find two numbers in two sorted arrays of integers. The format is A[i] + B[j] == x. The runtime of the algorithm needs to be O(n).
I thought i had it and wanted to check so I emailed my professor and she told me my runtime was O(n^2). Here is my code:
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5,6};
int x = 4;
int i = 0;
int j = 0;
for(int n = 0; n < (A.length*B.length); n++) {
if(i >= A.length)
i = 0;
if(n % B.length == 0)
j++;
if(A[i] + B[j] == x) {
System.out.println(A[i] + " + " + B[j] + " = " + x);
break;
}
i++;
}
EDIT
I do apologize if this is still incorrect. I never really grasped the concept of Big-Oh. Would this change the runtime to O(n)? I got rid of the A.length*B.length and tried something a little different.
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5};
int x = 5;
int i = 0;
int j = 0;
while(i < A.length) {
if(B[j] == x - A[i]) {
/* exit */ }
if(j >= B.length) {
j = 0;
i++; }
j++;
}
Solution 1:
Add all values in B to a Map with B value as the map key, and B-index as the map value.
Iterate A, and calculate desired B value as B = x - A. Look for it in the map, and if found, you then have the index.
You will only iterate A and B once each. Adding a single value to map is O(1), and looking up a value is O(1), assuming a HashMap, so overall is O(n).
Solution 2:
Iterate A ascending, and B descending.
For each value in A, look at current B value. Walk down B until A + B <= x (or you reach beginning of B).
You will only iterate A and B once each, so O(n).
Solution 2 requires less memory (no map), and is likely faster (no time spent building map).
UPDATE Here is code:
The above descriptions were based on need for index of values, and the code for each solution is:
Solution 1
private static void findSum(int[] a, int[] b, int x) {
Map<Integer, Integer> bIdx = new HashMap<>();
for (int j = 0; j < b.length; j++)
bIdx.put(b[j], j);
for (int i = 0; i < a.length; i++) {
Integer j = bIdx.get(x - a[i]);
if (j != null)
System.out.println("a[" + i + "] + b[" + j + "] = " + a[i] + " + " + b[j] + " = " + x);
}
}
Solution 2
private static void findSum(int[] a, int[] b, int x) {
for (int i = 0, j = b.length - 1, sum; i < a.length && j >= 0; i++) {
while (j >= 0 && (sum = a[i] + b[j]) >= x) {
if (sum == x)
System.out.println("a[" + i + "] + b[" + j + "] = " + a[i] + " + " + b[j] + " = " + x);
j--;
}
}
}
Test
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5,6};
findSum(a, b, 4);
Output (same from both)
a[0] + b[2] = 1 + 3 = 4
a[1] + b[1] = 2 + 2 = 4
a[2] + b[0] = 3 + 1 = 4
Solution 1 using Set
If you don't need index position, then a Set is better for solution 1:
private static void findSum(int[] aArr, int[] bArr, int x) {
Set<Integer> bSet = new HashSet<>();
for (int b : bArr)
bSet.add(b);
for (int a : aArr)
if (bSet.contains(x - a))
System.out.println(a + " + " + (x - a) + " = " + x);
}
Output
1 + 3 = 4
2 + 2 = 4
3 + 1 = 4
Here is an example of how you can measure your time, i've included another method to find the numbers you mentioned. See the difference in runtime:
int[] A = {1,2,3,4,5};
int[] B = {1,2,3,4,5,6};
int x = 4;
int i = 0;
int j = 0;
long t1 = System.nanoTime();
for(int n = 0; n < (A.length*B.length); n++) {
if(i >= A.length)
i = 0;
if(n % B.length == 0)
j++;
if(A[i] + B[j] == x) {
System.out.println(A[i] + " + " + B[j] + " = " + x);
break;
}
i++;
}
long t2 = System.nanoTime();
System.out.println("Time 1: "+(t2-t1));
//Here's the other method
long t3 = System.nanoTime();
for (int n = 0;n<B.length;n++){
for (int m =0;m<A.length;m++){
if(A[m]+B[n]==x){
System.out.println(A[m] +" + "+B[n] +" = "+ x);
}
}
}
long t4 = System.nanoTime();
System.out.println("Time 2: "+(t4-t3));
Here is the code, for Andreas's Solution 1, that I came up with:
int[] A = {2,3,4};
int[] B = {7,9};
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
int x = 10;
int b;
for(int i = 0; i < B.length; i++) {
hashMap.put(B[i], i);
}
for (int n = 0; n < A.length; n++){
b = x - A[n];
if(hashMap.get(b) != null)
System.out.println(A[n] + " + " + b + " = " + x);
}

Fill a 2-D array with all the factors of the numbers 1 to 1000 - java

I'm attempting to fill a 2D array with the numbers 1 to 1000 and then show all the factors of those numbers. I then need to find all the prime numbers in the same array and output them. Here's what I have so far, keep in mind that I was hoping to do every step in its own method then return them but have not got that far yet
int i = 0;
//int x = 0;
String primeNumber = "";
int[] [] factorArray = new int [1000] [];
for (int x = 0 ; x < 1000 ; x++)
{
int remainder;
int y;
remainder = x % 2;
y = x / 2;
if (remainder != 0)
System.out.println (x + ": " + "1, " + x);
else if (remainder == 0)
System.out.println (x + ": " + (y) + " , " + (y / 2) + " , " + " 1, " + x);
}
for (i = 1 ; i <= 1000 ; i++)
{
int ctr = 0;
for (int x = i ; x >= 1 ; x--)
{
if (i % x == 0){
ctr = ctr + 1;
}
}
if (ctr == 2)
{
primeNumber = primeNumber + i + " ";
}
}
System.out.print ("Prime numbers from 1 - 1000 are : \n" + primeNumber);

Calculate the number of pyramid

I'm trying to calculate the sum of the numbers in my pyramid in java. For this, mathematical rule is 2+5+8+9. I mean first row+first number of second row+ second number of third row like that.
int[] numbers = { 2,5,7,1,8,3,6,0,9,4 };
System.out.println(" " + numbers[0]);
System.out.println(" " + numbers[1] + " " + numbers[2]);
System.out.println(" " + numbers[3] + " " + numbers[4] + " " + numbers[5]);
System.out.println("" + numbers[6] + " " + numbers[7] + " " + numbers[8] + " " + numbers[9]);
For example:
2
5 7
1 8 3
6 0 9 4
How can I calculate 2+5+8+9 in Java?
The simplest way of calculating 2+5+8+9 is using Java build-in feature:
int result = 2+5+8+9;
You should construct your pyramid as a 2D array.
int[] numbers = { 2,5,7,1,8,3,6,0,9,4 };
int addedElements = 0;
int nextSize = 1;
ArrayList<int[]> pyramid = new ArrayList<>();
while(addedElements< numbers.size()) {
int[] level = new int[nextSize++];
for (int i = 0; i < nextSize - 1; i++) {
level[i] = numbers[addedElements++];
}
}
int result = 0;
//add maximum of each `int[]` in pyramid.
for (int[] array : pyramid) {
int currentMax = array[0];
for (int i = 0; i < array.size(); i++) {
if (array[i] > currentMax) {
currentMax = array[i];
}
result+=currentMax;
}
System.out.println(result);
Try the follwoing code :
int[] numbers = { 2,5,7,1,8,3,6,0,9,4 };
int index = 1;
int number = 2;
int result = numbers[0];
while (index < numbers.length) {
result += numbers[index + number -2];
index += number;
number += 1;
}
System.out.println(result);
But the whole whing would be much easier and clearer if you just put your pyramide into a 2 dimensional array.
int[][] numbers = { {2},
{5,7},
{1,8,3},
{6,0,9,4} };
int result = numbers[0][0];
for (int i = 1; i < numbers.length; i++) {
result += numbers[i][i-1];
}
System.out.println(result);

Categories