I'm having trouble trying to get the correct numbers to be in the correct position, my idea seems to be correct but the printing is incorrect.
static int plotTri1(int n, int i) {
if (n > 0) {
plotTri1(n - 1, n + i);
i += n;
for (; 0 < n; n--) {
System.out.printf("%3d", (i--));
}
System.out.println();
}
return n;
}
My current solution prints out the following:
Given n = 5 and i = 0
15
14 13
12 11 10
9 8 7 6
5 4 3 2 1
The desired solution is:
Given n = 5 and i = 0
1
3 2
6 5 4
10 9 8 7
15 14 13 12 11
Looking for help that will lead me to the desired solution
why do you use recursive function?
static void plotTri2(int n) {
int k=1 ;
for (int i=0; i<n; i++) {
for (int j=0; j<=i; j++) {
System.out.printf("%3d", new Object[] {new Integer(k-j)} );
}
k+= i+2 ;
System.out.println("");
}
}
plotTri2(5) ;
Here is an approach which worked for me. The basic idea is to print from the starting number in each row down the the last number in that row, recursively.
public static void triangle(int n, int num) {
if (n == 0) return;
triangle(n - 1, num - n);
System.out.println("\n");
for (int i=0; i < n; ++i) {
if (i > 0) System.out.print(" ");
System.out.print(num - i);
}
}
public static void main(String args[]) {
triangle(5, 15);
}
Demo
How about having the previous call return something? Here's one idea:
static int[] f(int n){
if (n == 0){
int[] firstRange = new int[]{1,1};
return firstRange;
}
int[] range = f(n - 1);
for (int i=range[0]; i<=range[1]; i++) {
System.out.printf("%3d", i);
}
System.out.println();
int[] nextRange = new int[]{range[1] + 1, 2 * range[1] - range[0] + 2};
return nextRange;
}
Related
I'm trying to develop a program that prints out Pascal's Triangle using recursion. Here are my codes:
public class PascalTriangle {
public static int[] computePT(int k) {
int[] pt = new int[k + 1];
if (k == 0) {
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k] = 1;
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
}
public class PascalTriangleDriver {
public static void main(String args[]) {
int k = 10;
int arr[] = PascalTriangle.computePT(k);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
}
The code runs perfectly, however my issue is that I want to modify my PascalTriangle code (not the PascalTriangleDriver code) such that when k=10, for example, it prints out:
1 9 36 84 126 126 84 36 9 1
instead of:
1 10 45 120 210 252 210 120 45 10 1
You seem to have made an off-by-1 error. One simple way to solve this is to write another method that calls your original method with k-1:
// this is your original method, just renamed:
private static int[] computePTImpl(int k) {
int[] pt = new int[k + 1];
if (k == 0) {
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k] = 1;
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
// you will call this method:
public static int[] computePT(int k) {
return computePT(k - 1);
}
Alternatively, you can actually fix your code by replacing ks with k-1s:
public static int[] computePT(int k) {
int[] pt = new int[k]; // note the change
if (k == 1) { // note the change
pt[0] = 1;
return pt;
} else {
int[] ppt = computePT(k - 1);
pt[0] = pt[k - 1] = 1; // note the change
for (int i = 1; i < ppt.length; i++) {
pt[i] = ppt[i - 1] + ppt[i];
}
}
return pt;
}
Note that we don't change the recursive call because if we did, we would be saying that the k-th row of Pascal's triangle depends on the k-2-th row, which is not true.
You can iteratively populate an array of binomial coefficients as follows: the first row and column are filled with ones, and all other elements are equal to the sum of the previous element in the row and column.
T[i][j] = T[i][j-1] + T[i-1][j];
You can create two methods: one returns a 2d array containing a triangle, and the second returns the base of that triangle. It is more useful for clarity.
Output:
Triangle:
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9
1 3 6 10 15 21 28 36
1 4 10 20 35 56 84
1 5 15 35 70 126
1 6 21 56 126
1 7 28 84
1 8 36
1 9
1
Base:
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
Code:
public static void main(String[] args) {
int n = 10;
System.out.println("Triangle:");
int[][] arr = binomialTriangle(n);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++)
if (arr[i][j] > 0)
System.out.printf("%2d ", arr[i][j]);
System.out.println();
}
int[] base = binomial(arr);
System.out.println("Base:");
System.out.println(Arrays.toString(base));
}
public static int[][] binomialTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
for (int i = 0; i < n; i++) {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the elements of the row
for (int j = 0; j < n - i; j++) {
if (i == 0 || j == 0) {
// elements of the first row
// and column are equal to one
arr[i][j] = 1;
} else {
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
}
}
}
return arr;
}
public static int[] binomial(int[][] arr) {
int[] base = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
// the last element in the row
base[i] = arr[i][arr[i].length - 1];
}
return base;
}
See also: Finding trinomial coefficients using dynamic programming
This is more of a logical question . Problem IS:
I need to fill a Matrix with number (1-9) In such a way so that :
No number should repeat in row
No number should repeat in column
Matrix can be from 3X3 to 8X8
Matrix should contain Random numbers not in some particular order
I am not good at putting logic what i have tried is below :
public class RandMatrix {
static int max=8;
static ArrayList<Integer> numbers=new ArrayList<>();
static int[][] arr=new int[max][max];
public static void main(String[] a){
// To fill number
for (int i = 1; i <=9; i++) {
numbers.add(i);
}
// Shuffle number
Collections.shuffle(numbers);
call();
}
public static void call(){
for (int i = 0; i < max; i++) {
for (int j = 0; j <max ; j++) {
for (int k = 0; k <max ; k++) {
int num=numbers.get(k);
if(!isExist(num,i,j)){
arr[i][j]=num;
break;
}
}
}
Collections.shuffle(numbers);
}
}
private static boolean isExist(int num,int row, int col){
for (int i = row; i >=0; i--) {
if(arr[i][col]==num){
return true;
}
}
for (int j = col; j >=0; j--) {
if(arr[row][j]==num){
return true;
}
}
return false;
}
}
When i print the 2-d array i see in some places there is still 0 as value . Seems like my code breaks. at some point there is no random number left which can be filled. Output is something like :
I know my algo is not right i just can not find a way to make it done .
Can i get some help on this.
I've saved and modified some the code a while ago so as to use if I need another time. I think it's for you ;)
import java.util.Arrays;
import java.util.Random;
class Test {
public static void main(String[] args){
int size = 9;
int[][] matrix= new int[size][];
matrix[0] = MatrixOps.createOrderedArray(size, 1);
for(int x=0; x < size; x++) {
matrix[x] = MatrixOps.createOrderedArray(size, 1);
do {
MatrixOps.shuffle(matrix[x]);
} while(! MatrixOps.compare2DArray(matrix[x], matrix, 0, x));
}
MatrixOps.print(matrix);
}
}
class MatrixOps {
public static void shuffle(int[] arr){
Random random = new Random();
for(int x = 0; x < arr.length; x++)
swap(arr, x, random.nextInt(arr.length));
}
public static int[] createOrderedArray(int size, int startValue) {
int[] num = new int[size];
for (int x = 0; x < num.length; x++)
num[x] = x + startValue;
return num;
}
public static boolean compare2DArray(int[] arr1, int[][] arr2, int begin, int end) {
for (int x = begin; x < end; x++)
if (!compareArray(arr1, arr2[x]))
return false;
return true;
}
// https://stackoverflow.com/questions/19648240/java-best-way-to-print-2d-array/41533179#41533179
public static void print(int[][] array) {
for (int[] x: array) {
for (int y: x) {
System.out.print(y + " ");
}
System.out.println();
}
}
private static boolean compareArray(int[] arr1, int[] arr2){
if(arr1.length != arr2.length)
return false;
for(int x=0; x<arr1.length; x++)
if(arr1[x] == arr2[x])
return false;
return true;
}
private static void swap(int[] arr, int a, int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
Example output:
5 1 7 2 3 8 9 4 6
4 3 1 5 7 9 2 6 8
9 7 3 8 6 2 4 5 1
6 8 4 3 5 7 1 9 2
1 5 8 9 2 6 7 3 4
7 9 2 6 4 1 5 8 3
8 6 9 4 1 5 3 2 7
3 2 6 7 9 4 8 1 5
2 4 5 1 8 3 6 7 9
Define the following matrix during startup:
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
When you need to create a n X n matrix do the following:
Randomly pick N numbers between 0-8 (without repeats) for row numbers ->R
Randomly pick N numbers between 0-8 (without repeats) for column numbers ->C
The elements of the final matrix will be M[x][y] = O[R[x]][C[y]]
The only problem is that the result is still not totally random. (It cannot generate ALL of the possible solutions.) Although the randomness is mentioned only in the title but not in the 3 requirements...
I think the best approach is to use a randomized backtracking algorithm.
The elements of the matrix are filled, one after the other. For each matrix element, we first enumerate all the remaining integers which can be used (based on the previous elements). Then each of them is tried in a random order untill the first solution is found.
public static void main(String[] args) {
int[][] matrix = getMatrix(7, 0L);
if (matrix != null) {
for (int row = 0; row < 7; ++row) {
for (int column = 0; column < 7; ++column) {
System.out.print(matrix[row][column]);
}
System.out.println();
}
}
}
public static int[][] getMatrix(int size, long seed) {
int[][] matrix = new int[size][size];
Random random = new Random(seed);
if (!backtrack(matrix, size, 0, random))
return null;
return matrix;
}
// returns true when the backtracking could succesfully fill the matrix
private static boolean backtrack(int[][] matrix, int size, int index, Random random) {
if (index == size * size) {
// all elements are filled without conflict
return true;
} else {
// find the row and column of the next element which need to be filled
int column = index % size;
int row = index / size;
// an array which indicates whether the numbers in range [1 - 9] can be used
// canUse[x] encodes whether number (x+1) can be used
boolean[] canUse = new boolean[9];
Arrays.fill(canUse, true);
// check the previous rows and column elements
for (int c = 0; c < column; ++c)
canUse[matrix[row][c] - 1] = false;
for (int r = 0; r < row; ++r)
canUse[matrix[r][column] - 1] = false;
// generate the list of possible entries
List<Integer> possibilities = new ArrayList<Integer>();
for (int i = 1; i <= 9; ++i)
if (canUse[i - 1])
possibilities.add(i);
// backtrack if there are no possible entries
if (possibilities.isEmpty())
return false;
// shuffle the list (to randomly fill the matrix)
Collections.shuffle(possibilities, random);
// enter the number
for (int possiblity : possibilities) {
matrix[row][column] = possiblity;
if (backtrack(matrix, size, index + 1, random))
return true;
}
return false;
}
}
Output:
4139562
1896375
2613857
9357124
6245931
3482619
8761493
Giving it a wild shot, not writing code. But thinking out:
How about start filling numbers column-wise, such that
mat[0][0]=1
mat[1][0]=2
...
mat[8][0]=9
Then when you starting filling the next column, do like:
mat[1][1]=1
mat[2][1]=2
...
mat[8][1]=8
mat[0][1]=9
and so on.
So its precisely filling the numbers sequentially and diagonally.
Using purely randomization to fill the matrix you will need to redo the last part of the result if you reach a dead end.
public static void call(){
int repeats = 0;
for (int i = 0; i < max; i++) {
for (int j = 0; j <max ; j++) {
for (int k = 0; k <max ; k++) {
int num=numbers.get(k);
if(!isExist(num,i,j)){
arr[i][j]=num;
break;
}
}
}
if(containsZero(arr[i]){
i--;
repeats++;
if(repeats > 1000){
i = 0;
repeats = 0;
}
}
Collections.shuffle(numbers);
}
}
private static boolean containsZero(int[] array){
for(int i = 0; i < array.length; i++){
if(array[i] == 0){
return true;
}
}
return false;
}
In some cases changing the last row isn't enough to guarantee that the matrix will be filled. That is why I added a counter which will reset the whole matrix if no solution can be found by changing the last row.
I have found a way for zigzag matrix but I am willing to find same as clean code for triangle pattern.
Example:
input = 3
Output:
1
32
456
I already coded a numbered matrix code here:
int k=0;
int t=1;
int n=4;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
k+=t;
System.out.print(k);
}
k=k+n+t;
t=-t;
System.out.println();
}
Output:
1234
8765
9101112
16151413
int n = 6;
int num = 0;
int step = 1;
for (int i = 1; i <= n; i++) {
// num : (i² - i + 2)/2 .. same + i - 1
for (int j = 0; j < i; j++) {
num += step;
System.out.print(num);
System.out.print(' ');
}
num += i + (1 + 3*step)/2;
step = -step; // zig resp. zag
System.out.println();
}
Helpful was numbering i as row with exactly i elements.
Yielding
1
3 2
4 5 6
10 9 8 7
11 12 13 14 15
21 20 19 18 17 16
The problem was that every row i of i numbers has a lowest value (i² - i + 2)/2,
and for the next zigzagging number one needs to consider the following step.
From the last row number to the first row number of the next line has two cases:
step -1
step 1
Both formulas of both cases can be unified by the step.
step i num
+ 1 1 -> 4 += i + 2
- 2 2 -> 3 += i - 1
+ 3 6 -> 11 += i + 2
- 4 7 -> 10 += i - 1
The following will work:
public static void zigZag(int rows) {
int current = 1;
int increment = 1;
for (int row = 1; row <= rows; row++) {
int width = row + current;
for (int element = current; element < width; element++) {
System.out.print(current);
current+=increment;
}
System.out.println();
current += row + 0.5 - (0.5*increment);
increment = -increment;
}
}
Edit: just a note because I suspect your question might be homework motivated, so it might help if you can understand what's going on instead of just copy-pasting.
All that really needed to change was to use the external loop variable (the one that was originally creating your matrix square, which I've called row) in the inner loop which prints the individual elements of the row.
This is then used to calculate the first element of the next row. The increment value does the same as it does in your original, but now it can also be used to have the zig-zag pattern go up in integers other than 1.
Starting from the top of the triangle (1) will be row 1, all subsequent even rows are printed in reverse. Knowing that you can try something like this:
public class StackOverflow {
public static void main(String[] args) {
int triangleSize = 5;
int counter = 1;
int rowSize = 1;
for (int i = 1; i <= triangleSize; i++) {
if (i % 2 == 0) {
// Reverse number sequence
int reverseCounter = counter + rowSize - 1;
for (int j = 0; j < rowSize; j++) {
System.out.print(reverseCounter--);
counter++;
}
} else {
for (int j = 0; j < rowSize; j++) {
System.out.print(counter++);
}
}
System.out.println("");
rowSize++;
}
}
}
Keep track what row you're on (rowSize) and what value you're on (counter). When you're on an even row you have to start with the highest value that row will have and count backwards from it, but still increment your normal counter (int reverseCounter = counter + rowSize + 1).
Result:
1
32
456
10987
1112131415
Try this I coded it for you:
public class TriangleNum{
public static void main(String[] args) {
getTringle(5);
}
public static void getTringle(int j){
for (int i =0; i<j;i++) {
System.out.print(i+ "\r" );
for (int k =0; k<i;k++) {
System.out.print(k+ "\t" );
}
}
}
}
//Using C Language
#include<stdio.h>
int main(){
int n,count=1,k=1;
printf("Enter number of lines:\n");
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(i%2==1){printf("%d",count);count++;}
else{printf("%d",count);count--;}}
count=count+k;
if(i%2==1){k=k+2;}
printf("\n");
}
return 0;
}
I am trying to write code for bucket sort, but am confused in bucket size of each bucket. My code is below.
input array: {12, 11, 13, 5, 6, 7,10,22,4,16,1,26};
I am passing bucket size of each bucket >3 then I dont get the output in sorted order. It gives perfect ans for bucket size 1 and 2
public void bucsort(int[] arr,int bucketSize){
if(arr.length==0) return;
int max=arr[0];
int min=arr[0];
for(int i=0; i<arr.length;i++){
if(arr[i]<min)
{
min=arr[i];
}
else
max=arr[i];
}
int bucketCount= (max - min) / bucketSize + 1;
List<List<Integer>> buckets = new ArrayList<List<Integer>>(bucketCount);
// int divider= (max+1)/bucketCount;
for (int i = 0; i < bucketCount; i++) {
buckets.add(new ArrayList<Integer>());
}
for (int i = 0; i < arr.length; i++) {
buckets.get((arr[i]-min) / bucketSize).add(arr[i]);
}
int currentIndex = 0;
for (int i = 0; i < buckets.size(); i++) {
Integer[] bucketArray = new Integer[buckets.get(i).size()];
bucketArray = buckets.get(i).toArray(bucketArray);
InsertionSort(bucketArray);
for (int j = 0; j < bucketArray.length; j++) {
arr[currentIndex++] = bucketArray[j];
}
}
}
Is there any relation between no. of buckets and its size ?
I edited my method for max-min function and also debugged the program. There seems to be some mistake in my insertion sort
the code is:
public void InsertionSort(Integer[] arr){
for(int i=1; i<arr.length; i++){
int value=arr[i];
int hole=i;
while(hole>0 && arr[hole-1]>value){
arr[hole]=arr[hole-1];
hole--;
}
arr[hole-1]=value;
}
}
main func
public static void main(String[] args) {
int arr[] = {12, 11, 13, 5, 6, 7,10,22,4,16,1,26};
BucketSort ob = new BucketSort();
ob.bucsort(arr, 5);
printArray(arr);
}
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
My output for bucket size 5 : 5 1 4 6 7 10 12 11 13 16 22 26
for size 3: 1 5 4 6 7 12 10 11 13 16 22 26
for size 2: 1 4 5 6 7 10 12 11 13 16 22 26
Finding max-min is wrong...(you have some logical error)
int minValue = array[0];
int maxValue = array[0];
for (int i = 1; i < array.Length; i++) {
if (array[i] < minValue) {
minValue = array[i];
} else if (array[i] > maxValue) {
maxValue = array[i];
}
}
On your code:
1 4 3
min 1 1 1
max 1 4 3
This will be the correct implemenation
for (i = 1; i < length; i++) {
j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
j--;
}
}
I will debug your code when I get time..
In your InsertionSort method you do
int value=arr[i];
int hole=i;
while(hole>0 && arr[hole]>value){
At this point arr[hole] will always equal value, so you never get into the while loop. So nothing gets sorted. For small bucket sizes, you may be lucky that it doesn’t matter. For bucket size 1, it certainly doesn’t. Even for bucket size 2 you have a single error in the sorting. I get:
1 4 5 6 7 10 12 11 13 16 22 26
12 comes before 11 because those two numbers end up in the same bucket and don’t get sorted.
I took this from your comment: while (hole > 0 && arr[hole - 1] > value) {. On your request, now the method looks like this:
public void insertionSort(Integer[] arr) { // renamed to small i since it’s a method
for (int i = 1; i < arr.length; i++) {
int value = arr[i];
int hole = i;
while (hole > 0 && arr[hole - 1] > value) {
arr[hole] = arr[hole - 1];
hole--;
}
arr[hole] = value;
}
}
Now I get correct sorting with all bucket sizes from 1 to 19. If you still have a problem, there must be something we are not doing the same way.
It’s an aside, but as has been mentioned a couple of times, there is a bug in your code for finding max. I tried this input:
int arr[] = { 3, 10, 4 };
I get a maxof 4 (expected: 10) and then a java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at this line:
buckets.get((arr[i]-min) / bucketSize).add(arr[i]);
I have an exercise in which I have to sort an array in the following way:
the numbers that divide 4 with no remainder will be the first in the array (e.g 4,8,12,16).
the numbers that divide 4 with remainder of 1 will be the second in the array (1,5,9).
the numbers that divide 4 with remainder of 2 will be the third in the array (2,6,10).
the numbers that divide 4 with remainder of 3 will be last in the array.
For example, the following array:
int []a={1,7,3,2,4,1,8,14}
will be:
4 8 1 1 2 14 3 7
the order within the groups does not matter.
I have found a solution which works on O(n) time complexity and O(1) space complexity.
However, it is ugly and moves on the array 3 times. I would want a more elegant solution.
This is my code:
int ptr=a.length-1; int temp=0, i=0;
while (i<ptr){
//move 3 remained to the end
if (a[i] % 4==3){
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==2)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==1)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
Important to know:
I don't want time complexity worse than O(n), and space complexity worse than O(1).
Since O(3 * N) is O(N), you only need to loop through the array three times:
Move the elements e % 4 == 0 to the front, swapping elements along the way;
Move the elements e % 4 == 1 to the front, swapping elements along the way;
Move the elements e % 4 == 2 to the front, swapping elements along the way;
The elements that e % 4 == 3 will be at the end after this.
Example:
public static void main(String args[]) {
int[] a = { 1, 7, 3, 2, 4, 1, 8, 14 , 9};
int current = 0;
for (int i = 0; i < 3; i++) {
for (int j = current; j < a.length; j++) {
if (a[j] % 4 == i) {
int b = a[j];
a[j] = a[current];
a[current] = b;
current++;
}
}
}
System.out.println(Arrays.toString(a));
}
Just use a comparator and make use for the very efficient internal sort algorithm.
Arrays.sort(a, new Comparator() {
public int compare(int a, int b) {
if(a%4 == b%4) {
if(a < b) return -1;
if(a > b) return 1;
return 0;
} else {
if(a%4 < b%4) return -1;
if(a%4 > b%4) return 1;
return 0;
}
}
});
You can use up more memory. This is not correct, but I will still put it.
int modulusLength = 4;
List<Integer> array[] = new List<Integer>[modulusLength];
for(int i = 0; i < modulusLength; i++)
array[i] = new ArrayList<Integer>;
for(int i = 0 ; i < a.length; i++)
array[a[i]%modulusLength].put(a[i]);
int counter = 0;
for(int i = 0 ; i < array.length; i++)
for(int j = 0; j < array[i].size; j++)
{
a[counter] = array[i].get(j);
counter++;
}
Horrible and scary, but was fun to write. And it works :)