Calculating matrix sqaure determinant - java

I'm trying to code a function that calculates a sqaured-matrix determinant (of which all numbers of the diagonal are multiplied) for self coding. I got the main idea but I can't get the right result because of some calculation error. this is the code I wrote:
public static int det(int[][] matrix, int n) {
int i,j, k, det=1;
for (i=0; i < matrix.length; i++) {
for (j=0; j < matrix[i].length; j++) {
if (i<j)
if(matrix[i][j] == 0) {
//isTriangle = true;
det *= matrix[i][i];
}
if (i>j)
if (matrix[i][j] == 0) {
//isTriangle = true;
det *= matrix[i][i];
}
}
}
return det;
}
After I run this function I get results that don't include the final number (matrix[n][n]) because it wasn't multiplied for some reason. Next thing I tried to set a for loop that will multiply all the members of the diagonal (det *= matrix[k][k]) outside the two loops but then I got very high numbers as a result. What am I doing wrong with the math here?

Your algorithm is not correct. It should look like this:
Make the input matrix triangular using Gaussian elimination.
Multiply all numbers on the diagonal(that is, find a product of matrix[i][i] for all i).
You cannot skip the first step.

You can also use a recursion.
Given the n by n matrix M, we create W(i,j) by striking out column i and row j of M.
So for the 3 x 3 matrix:
1 2 3
4 5 6
7 8 9
W(0,0) =
5 6
8 9
W(1,0) =
4 6
7 9
etc.
Now you can expand around any row or column.
Additionally you need to alternate + and -; for a 3 x 3 Matrix it would look like this:
+ - +
- + -
+ - +
So expanding around column 2, we get:
+ 3 * det
4 5
7 8
- 6 * det
1 2
7 8
+ 9 * det
1 2
4 5
Or
-1^(2+0) * M(2,0)*det(W(2,0))
+ -1^(2+1) * M(2,1)*det(W(2,1))
+ -1^(2+2) * M(2,2)*det(W(2,2))
I am deliberately working from example because the formula looks a bit scary:
det(M) = sum(i=0 to N-1){ -1 ^ i * M(i,0) * det(W(i,0)) }
Note that in this formula that we are expanding around the first row (instead of the third column as before)

Related

Meaning of the formula how to find lost element in array?

The task is to find lost element in the array. I understand the logic of the solution but I don't understand how does this formula works?
Here is the solution
int[] array = new int[]{4,1,2,3,5,8,6};
int size = array.length;
int result = (size + 1) * (size + 2)/2;
for (int i : array){
result -= i;
}
But why we add 1 to total size and multiply it to total size + 2 /2 ?? In all resources, people just use that formula but nobody explains how that formula works
The sum of the digits 1 thru n is equal to ((n)(n+1))/2.
e.g. for 1,2,3,4,5 5*6/2 = 15.
But this is just a quick way to add up the numbers from 1 to n. Here is what is really going on.
The series computes the sum of 1 to n assuming they all were present. But by subtracting each number from that sum, the remainder is the missing number.
The formula for an arithmetic series of integers from k to n where adjacent elements differ by 1 is.
S[k,n] = (n-k+1)(n+k)/2
Example: k = 5, n = 10
S[k,n] = 5 6 7 8 9 10
S[k,n] = 10 9 8 7 6 5
S[k,n] = (10-5+1)*(10+5)/2
2S[k,n] = 6 * 15 / 2
S[k,n] = 90 / 2 = 45
For any single number missing from the sequence, by subtracting the others from the sum of 45, the remainder will be the missing number.
Let's say you currently have n elements in your array. You know that one element is missing, which means that the actual size of your array should be n + 1.
Now, you just need to calculate the sum 1 + 2 + ... + n + (n+1).
A handy formula for computing the sum of all integers from 1 up to k is given by k(k+1)/2.
By just replacing k with n+1, you get the formula (n+1)(n+2)/2.
It's simple mathematics.
Sum of first n natural numbers = n*(n+1)/2.
Number of elements in array = size of array.
So, in this case n = size + 1
So, after finding the sum, we are subtracting all the numbers from array individually and we are left with the missing number.
Broken sequence vs full sequence
But why we add 1 to total size and multiply it to total size + 2 /2 ?
The amount of numbers stored in your array is one less than the maximal number, as the sequence is missing one element.
Check your example:
4, 1, 2, 3, 5, 8, 6
The sequence is supposed to go from 1 to 8, but the amount of elements (size) is 7, not 8. Because the 7 is missing from the sequence.
Another example:
1, 2, 3, 5, 6, 7
This sequence is missing the 4. The full sequence would have a length of 7 but the above array would have a length of 6 only, one less.
You have to account for that and counter it.
Sum formula
Knowing that, the sum of all natural numbers from 1 up to n, so 1 + 2 + 3 + ... + n can also be directly computed by
n * (n + 1) / 2
See the very first paragraph in Wikipedia#Summation.
But n is supposed to be 8 (length of the full sequence) in your example, not 7 (broken sequence). So you have to add 1 to all the n in the formula, receiving
(n + 1) * (n + 2) / 2
I guess this would be similar to Missing Number of LeetCode (268):
Java
class Solution {
public static int missingNumber(int[] nums) {
int missing = nums.length;
for (int index = 0; index < nums.length; index++)
missing += index - nums[index];
return missing;
}
}
C++ using Bit Manipulation
class Solution {
public:
int missingNumber(vector<int> &nums) {
int missing = nums.size();
int index = 0;
for (int num : nums) {
missing = missing ^ num ^ index;
index++;
}
return missing;
}
};
Python I
class Solution:
def missingNumber(self, nums):
return (len(nums) * (-~len(nums))) // 2 - sum(nums)
Python II
class Solution:
def missingNumber(self, nums):
return (len(nums) * ((-~len(nums))) >> 1) - sum(nums)
Reference to how it works:
The methods have been explained in the following links:
Missing Number Discussion
Missing Number Solution

Getting median out of frequency table (counting sort)

I can't understand the logic behind getMedian method. How exactly median is evaluated, what is the connection between count of elements and sum of elements? Appreciate if someone could explain it's logic.
public static void main(String[] args) {
Random r = new Random();
int[] ar = r.ints(0, 100).limit(9).toArray();
int k = ar.length;
int[] count = getCounts(ar);
double median = getMedian(count, k);
System.out.println(median);
}
private static int[] getCounts(int[] ar) {
int[] count = new int[100];
for (int i = 0; i < ar.length; i++) {
count[ar[i]]++;
}
return count;
}
private static double getMedian(int[] count, int d) {
int sum = 0;
for (int i = 0; i < count.length; i++) {
sum += count[i];
if (2 * sum < d)
continue;
else if (2 * sum == d)
return (2 * i + 1) / 2.0;
else
return i * 1.0;
}
return -1.0;
}
There is a relation because it is a frequency table. You are thinking it differently but let me give you an example.
1 1 1 3 3 4 4 4 5 5 5 5 if this is the array then the frequency table would be :-
1 3 4 5
- - - -
3 2 3 4
So this is median.
So now I am adding every element count and asking us the question, where does the median lie? or where is that indexm which if I consider I will cover the middle element?
Now here I am checking if sum > d/2 then it's done. We found the median.else if it is less then I still have to traverse other elements to get to the middle of the array. And if it is sum==d/2 then we have found it but we have to send the correct position. And we simply send the one in the lower middle (happens in case like 1,1,1,1).
Walk through
1 1 1 3 3 4 4 4 5 5 5 5
Now I check if I traverse all set of 1's where I am? I covered 3 elements. But it's not the half of the total numbers(6).
Now add number of 3's. 5. This is also not.
Now I add number of 4's, So 8 elements I covered. So I covered more than half of number of elements. So median lies here.
More detailed explanation:
You are asked to find the median of an array of 10 integers.
[1 2 3 4 5 6 7 8 9]
Then median is in element at position floor(9/2)=4, which is 5 Right?
[1 1 2 2 3 3 4 4 5]
Where is the median element at position floor(9/2)=4, which is 3. Right?
So now think this,
1 2 3 4 5
2 2 2 2 1
Now you will try to find the floor(9/2) th element here starting from beginning. And that's why you need to find the sum of the frequencies and all.
Hope you get it?
Correct algorithm
What you need to do is :-
N = number of elements.
F[] = frequency array
so if N is odd
find the element at floor(N/2)-th place and median is that element.
else
find the element at floor((N-1)/2) and floor(N/2) th position and return their average.
Finding the element is simple:
Find( F[], p) // find the element at position p
{
p=p+1
for i in [0..|F|]
cumulative+=F[i]
if cumulative == p
return this element.
else cumulative >p
return this element
}

CodeAbbey Challenge 14 data entry issues?

int fnum = Integer.parseInt(split[0]);// holds 5
//split[] holds each line of the file.
double sum = fnum;// sum = 5
double i = 0.0;
double last = 0.0;
for(int j = 1; j<(split.length-1);j++)
{
i = Integer.parseInt(split[j].replaceAll("[^0-9]", ""));
if(split[j].charAt(0) == '*')
{
sum = sum * i;
}
else if(split[j].charAt(0) == '/')
{
sum = sum / i;
}
else if(split[j].charAt(0) == '+')
{
sum = sum + i;
}
else if(split[j].charAt(0) == '-')
{
sum = sum - i;
}
else if(split[j].charAt(0) == '%')
{
sum = sum % i;
}
}
System.out.println(sum);// Prints 1.0
}
}
/*
Actual Data File Imported
5
+ 3
* 7
+ 10
* 2
* 3
+ 1
% 11
Answer should be : 1
*/
Alright My code may look messy, but I tried hard on it. Gave up a few times but tried again. My question is for smaller data sets such as the one I imported and commented out on the code on the last few lines, work fine. But for bigger data sets it's all wrong why is that? I've tried making al my data sets double to get bigger values but somehow it's wrong?
I'm a beginner so far, any help would be greatly appreciated.
To be more specific on the problem I imported the file, I made it all a String, line by line, then I added it all in a String array so each line was in a string array for example split[1] would print + 3. Now after that I isolated the number and the symbol in the if loop wrapped in a forloop to go over all the sets. Now the if loop captures the symbols and then does the appropriate arithmetic. SomeHow it didn't though? And I used a double instead of an int for sum. That didn't help.I believe the if statement could be the issue.
Not sure if you still need the answer but, here's a tip:
The whole point of that specific exercise was to learn the modular arithmetic, which is that if you sum up/multiply the remainders of all of the numbers, you get the same answer as you would using the numbers given, that is if you apply the same number that's after % for all of them.
For example:
14
+ 78
* 9
* 3
+ 4
% 3
After all of the applied operations, the numbers above % 3 result in 2488.
And so 2488 % 3 = 1.
So if you apply % 3 to each one of the numbers, including the initial one, you get the same answer, using the same operations on their remainders of course and dividing the sum again by 3.
14 % 3 = 2
78 % 3 = 0
9 % 3 = 0
3 % 3 = 0
4 % 3 = 1
So, you get 2 + 0 * 0 * 0 + 1 which equals to 1.
And 1 % 3 = 1 which is the same as 2488 % 3 = 1.
My point being, you should apply modulo to every one of the numbers, so you get little numbers and don't even have the big ones you're having problems with.
Hope this was clear enough and hope it helps.

For loop to print the number in sequence and reverse it

How to print the following output with only one for-loop in java?
1 2 3 4 5 6 7 8 9 1 0 9 8 7 6 5 4 3 2 1
Code snippet:
class Series{
public static void main(String args[]){
for(int i=1; i<=10; i++){
System.out.println(i);
}
System.out.println(i);
for(int j=9; j>=0; j--){
System.out.println(j);
}
}
My program's in the following manner. Can anyone correct it?
public static void main(String...strings ){
int dir = 1;
for(int i=1; i>0; i+=dir){
if(i == 10)
dir = -1;
System.out.print(i+" ");
}
}
Output:
1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
The series in the question is wrong.
It should be: 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
The code, in one loop, is as follows:
int ctr = 1;
for(int i = 1; i > 0; i += ctr)
{
if(i == 10)
{
ctr = -1;
}
System.out.print(i + " ");
}
Every sequence follows a pattern, Let's try finding one in this.
To work with this code, analyze What loop would print with the variable that you increment and What you want in the output?
In your problem, assuming that the number you are entering is entered by user i.e. n, you want 2*n - 1 numbers in your sequence. Hence we now have the limits of our loop
For n=5, Under no Conditions the loop would simply print a sequence like this
1 2 3 4 5 6 7 8 9 provided you are starting your loop from 1.
The sequence you want is 1 2 3 4 5 4 3 2 1.
Now looking at both the sequences you can see that the sequence is same till the mid point that is till the value of n is reached. Now if you observe the pattern further if you subtract 2 from 6 you get 4 that is the number you want in your sequence. Similarly when you subtract 4 from 7 you get 3 which is the next number in the sequence you required.
Hence the pattern this sequence follows is that after the loop reaches the value provided by the user you need to subtract (2 * k) from the next number where k starts from 1 and increases with every iteration
Now you know how to achieve the pattern which would be easy to achieve using conditional statements.
PS: let's assume an added constraint of using no conditional statements then we have to write an arithmetic expression to solve our problem.
Following the pattern again the expression must display i where i is the variable incremented in the loop
so our code looks like
for (i = 1; i<=2*n - 1;i++)
{
System.out.print(i);
}
Now to get the pattern we need to subtract multiples of 2 after the user provided integer n is reached. But whatever we subtract should also not affect out first n integers.
Since we know we have to subtract multiples of 2 we know the expression we have to subtract would look like 2 * (____). As we want a sequence of multiples we can obtain that using %. As soon as the number goes over n the % operator on i would give us back sequence from 0 to n-1 hence generating multiples of 2.
Now our expression comes to 2 * (i % n). But the problem is that it would also subtract from the first 4 integers which we don't want so we have to make changes such that this expression will work only after loop reaches the value provided by the user.
As we know the division / operator provides us with the quotient. Hence it would yield us 0 till we reach the value of user defined number and 1 for the rest of the sequence as we run our loop till 2*n -1. Hence multiplying this expression to our previous expression yields 2*(i%n)*(i/n)
And there we have it our final code to generate the sequence would be
for (int i = 1;i<2*r;i++)
{
System.out.print(i - 2 * (i%r)*(i/r));
}
Observe the above code for the first n-1 integers i/r would make subtracted expression 0 and for i = n, i % r would make the expression 0. For the rest of the sequence i / r would generate value 1 and hence we will get multiples of 2 from 2 *( i % r) to provide us with the sequence
try this
int j = 10;
for (int i = 1; i <= 10; i++) {
if(i<10)
System.out.print(" " +i);
if(i==10){
i--;
System.out.print(" " +j);
if(j==1){
i++;
}
j--;
}
}
OutPut
1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
Something like this?
for(int i=0;i<20;i++) {
if((i/10)%2 == 0)
System.out.print(i%10 + " ");
else
System.out.print((10-(i%10)) + " ");
}
Try this code, You just need a if condition in for loop.
int i = 1;
for(int j=1; j<=20; j++)
{
if(j<11)
System.out.print(j+" ");
else
{
System.out.print((j - i == 10 ?" ": (j-i + " ")));
i = i+2;
}
}
public class forLoopTest {
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
System.out.print(i + " ");
}
for (int j = 10; j >= 1; j--) {
System.out.print(j + " ");
}
}
}

Creating a looping square with java

Full Disclosure: Homework.
Explanation: I cant understand my teacher.
Problem:
Write a method called printSquare that takes in two integer
parameters, a min and a max, and prints the numbers in the range from
min to max inclusive in a square pattern. The square pattern is
easier to understand by example than by explanation, so take a look at
the sample method calls and their resulting console output in the
table below. Each line of the square consists of a circular sequence
of increasing integers between min and max. Each line prints a
different permutation of this sequence. The first line begins with
min, the second line begins with min + 1, and so on. When the
sequence in any line reaches max, it wraps around back to min. You
may assume the caller of the method will pass a min and a max
parameter such that min is less than or equal to max
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
This is what I have so far, apologies but I have trouble with for loops.
for(int i = 0; i < row; i++)
{
for(int d = 0; d < row; d++)
{
System.out.print(d+1);
}
System.out.println(i);
}
I know I used row twice, but its the only way i can get the compiler to form a square shape with the loop. Does anyone even remotely understand what i'm trying to do? :/
This is actually a nice mathematical problem. Assume:
int side = to - from + 1; /// the size/width of the square.
the value at any point in the square (row, col) is:
from + ((row + col) % side)
you should be able to put that in your loops and "smoke it".
Edit based on comment asking for explanation.
The trick is to loop through all the positions in the 'matrix'. Given that the matrix is square, the loops are relatively simple, just two loops (nested) that traverse the system:
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
... magic goes here....
}
}
Now, in this loop, we have the variables row and col which represent the cell in the matrix we are interested in. The value in that cell needs to be proportional to the distance it is from the origin..... let me explain.... If the origin is the top left (which it is), then the distances from the origin are:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
The distance is the sum of the row and the column...... (rows and columns start counting from 0).
The values we put in each matrix are limited to a fixed range. For the above example, with a square of size 5, it could have been specified as printSquare(1,5).
The value in each cell is the from value (1 in this example) plus the distance from the origin... naively, this would look like:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
here the values in the cell have exceeded the limit of 5, and we need to wrap them around... so, the trick is to 'wrap' the distances from the origin..... and the 'modulo' operator is great for that. First, consider the original 'origin distance' matrix:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
if we instead populate this matrix with 'the remainder of the distance when dividing by 5' (the modulo 5, or %5) we get the matrix:
0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3
Now, if we add this 'modulo' result to the from value (1), we get our final matrix:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
in a sense, all you need to know is that the value at each cell is:
the from value plus the remainder when you divide the 'distance' by the width.
Here's the code I tested with:
public static final String buildSquare(final int from, final int to) {
final StringBuilder sb = new StringBuilder(side * side);
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
sb.append( from + ((row + col) % side) );
}
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(buildSquare(1, 5));
System.out.println(buildSquare(3, 9));
System.out.println(buildSquare(5, 5));
System.out.println(buildSquare(0, 9));
System.out.println(buildSquare(0, 3));
}
Since this is homework, I'll just give a hint.
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
Here's one way to do it.
Create the first number twice in an array. Taking the printSquare(1, 5) example, create an int array of 1, 2, 3, 4, 5, 1, 2, 3, 4, 5.
Use a loop to loop through the array, starting with element zero and ending with element 4, and another loop to display 5 digits (max - min + 1).
try this
int i,j,k;
for(i=min;i<=max;i++) {
for(j=i;j<=max;j++) {
System.out.print(j);
}
for(k=min;k<i;k++){
System.out.print(k);
}
System.out.println();
}
you can try
loop from min value to max value and put all the numbers in an array
now loop again from min value to max value
each time print the array and do a circular shift (for circular shift you can find lot of example in SO)
I think #rolfl's solution is the cleanest. I'd recommend going with that.
You can find another simple solution by observing that each output in your "square" simply shifts the first element to the end the list of numbers. To imitate this, you can put all the numbers from min to max in a data structure like LinkedList or ArrayDeque where you can easily add/remove items from both ends, then you'd print the contents in order, and shift the first entry to the end. E.g., coll.addLast(coll.removeFirst()). If you repeat that process max - min + 1 times, you should get the desired output.
no array no problem you can easily solve.
it work with any range of number.
static void printSquare(int min, int max){
int len = max - min + 1;
int copy_min = min, permanent_min = min;
for(int i = 0; i < len; i++){
for(int j = 0; j< len; j++){
if(min > max)
if(min % len < permanent_min)
System.out.print((min % len )+ len);
else
System.out.print(min % len);
else
System.out.print(min);
min++;
}
min = ++copy_min;
System.out.println();
}
}
public static void printSquare(int min, int max)  {
    
    for (int i = min; i <= (max -min)+min; i++)  {
        
        for( int j =i; j <= max ; j++) {                
            System.out.print(j);   
            } 
        for (int j1= min; j1<= i * 1 - 1; j1++) {
            System.out.print(j1);
            }
        System.out.println();
    }
    
}

Categories