Print Pascal's Triangle using recursion - java

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

Related

Adding 2 differently sized 2d arrays together

I am trying to add two differently sized matrices together. For example, the resultant matrix should be matOne[0][0]+matTwo[0][0]; however, I am having trouble taking into account their different sizes (if there's a missing value, it should be assumed it's a 0).
Here's my code:
int[][] go(int[][] matOne, int[][] matTwo)
{
int size= Math.max(matOne.length, matTwo.length);
int[][] matThree= new int [size][];
int c;
for (int i=0; i<size; i++) {
c= Math.max(matOne[i].length, matTwo[i].length);
for (int j = 0; j < c; j++) {
if (matOne[j].length > i) {
matThree[i][j] += matOne[i][j];
}
if (matTwo[j].length > i) {
matThree[i][j] += matTwo[i][j];
}
}
}
return matOne;
}
I see the following bugs in the code:
You never allocate the inner arrays. After you get size, you correctly create the outer array. After you get c, you forget to create the inner array for that row.
Right inside the i loop, one of matOne[i] and matTwo[i] is likely to fail eventually, whichever one is shorter.
Variable i iterates over rows, and variable j iterates over columns in a row, which means that the [i][j] in the += statements are correct, but that the matOne[j].length > i should have been matOne[i].length > j. Same for matTwo.
You return the wrong array.
Here is the fixed code, using better variable names:
static int[][] go(int[][] matOne, int[][] matTwo) {
int rows = Math.max(matOne.length, matTwo.length);
int[][] matThree = new int [rows][];
for (int r = 0; r < rows; r++) {
int cells = Math.max((matOne.length > r ? matOne[r].length : 0),
(matTwo.length > r ? matTwo[r].length : 0));
matThree[r] = new int[cells];
for (int c = 0; c < cells; c++) {
if (matOne.length > r && matOne[r].length > c) {
matThree[r][c] += matOne[r][c];
}
if (matTwo.length > r && matTwo[r].length > c) {
matThree[r][c] += matTwo[r][c];
}
}
}
return matThree;
}
Test
public static void main(String[] args) {
int[][] matOne = { { 1, 2, 3 }, { 4, 5, 6 } };
int[][] matTwo = { { 7, 8 }, { 9, 10 }, { 11, 12 } };
int[][] matThree = go(matOne, matTwo);
print(matOne);
System.out.println("+");
print(matTwo);
System.out.println("=");
print(matThree);
}
static void print(int[][] mat) {
for (int[] row : mat) {
for (int cell : row)
System.out.printf(" %2d", cell);
System.out.println();
}
}
Output
1 2 3
4 5 6
+
7 8
9 10
11 12
=
8 10 3
13 15 6
11 12
If you don't want the result to be a jagged array, i.e. you want the result to be a 2D rectangular matrix, change the code as follows:
static int[][] go(int[][] matOne, int[][] matTwo) {
int rows = Math.max(matOne.length, matTwo.length);
int cols = 0;
for (int[] row : matOne)
cols = Math.max(cols, row.length);
for (int[] row : matTwo)
cols = Math.max(cols, row.length);
int[][] matThree = new int [rows][cols];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (matOne.length > r && matOne[r].length > c) {
matThree[r][c] += matOne[r][c];
}
if (matTwo.length > r && matTwo[r].length > c) {
matThree[r][c] += matTwo[r][c];
}
}
}
return matThree;
}
Output
1 2 3
4 5 6
+
7 8
9 10
11 12
=
8 10 3
13 15 6
11 12 0
Just before the inner loop; replace current calculation of 'c' and allocate a row for matThree.
c = 0;
if (i < matOne.length)
c = matOne[i].length;
if (i < matTwo.length && matTwo[i].length > c)
c = matTwo[i].length;
matThree[i] = new int[c];
The code inside the inner loop should be:
int elem1 = 0, elem2 = 0;
if (i < matOne.length && j < matOne[i].length)
elem1 = matOne[i][j];
if (i < matTwo.length && j < matTwo[i].length)
elem2 = matTwo[i][j];
matThree[i][j] = elem1 + elem2;
Firstly, it's necessary to allocate storage for the current row of matThree.
Secondly, you need to check that both row and column are within bounds for each matrix. For my taste it's clearest to explicitly extract the values, defaulting to zero, thus the variables elem1 and elem2.

Recursive number triangle

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;
}

bucket size in bucket sort

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]);

Code has incorrect last value in array

I can not find why the code has the last incorrect value for test 3 and 5. I can not change the array to array list. The methods are the only thing that I can change.
package Semester;
import java.util.ArrayList;
public class MemberArrayList {
private ArrayList<Integer> friendsScore = new ArrayList<Integer>();
private ArrayList<String> friendsID = new ArrayList<String>();
// Add a friend with ID with the score into friends.
public void addFriend(String friendID, int score) {
// TODO
friendsScore.add(score);
friendsID.add(friendID);
}
// Removes a friend with friendID, but you cannot use indexOf. Only methods you can use: size, equals, get, remove
public void removeFriend(String friendID) {
// TODO
for (int i = 0; i < friendsID.size(); i++)
{
if ( friendID.equals(friendsID.get(i)))
{
friendsScore.remove(i);
friendsID.remove(i);
}
}
}
// Get the scores of first 10 friends added
public int [] getScores10() {
// TODO
int size = 10;
int[] score = new int[size];
for (int i = 0; i < 10; i++)
{
score[i] = friendsScore.get(i);
}
return score;
}
public int [] getScoresLast10() {
// TODO
int[] score = new int[10];
int j = 0;
for (int i = friendsScore.size()-1; i > (friendsScore.size()-10); i--)
{
score[j] = friendsScore.get(i);
j++;
}
return score;
}
// Get the scores of the friends in the array, but you cannot use indexOf function. You can only use size, get, equals, intValue
public int [] getScores(String [] friendIDs) {
// TODO
int value = friendIDs.length;
int[] score = new int[value];
for (int i = 0; i < value; i++)
{
String person = friendIDs[i];
for (int j = 0; j < friendsID.size(); j++)
{
if (person.equals(friendsID.get(j)))
{
score[i] = friendsScore.get(j);
}
}
}
return score;
}
public static void main(String[] args) {
MemberArrayList member = new MemberArrayList();
member.addFriend("Paul", 3);
member.addFriend("Peter", 1);
member.addFriend("Mary", 2);
member.addFriend("John", 4);
member.addFriend("Karen", 7);
member.addFriend("Kevin", 3);
member.addFriend("Walter", 1);
member.removeFriend("Mary");
member.removeFriend("Walter");
member.addFriend("Steven", 21);
member.addFriend("Kelly", 9);
member.addFriend("Kaitlin", -5);
member.addFriend("Bea", 77);
member.addFriend("Max", 32);
System.out.println("Test 1");
String [] friendIDs = {"Paul","Kevin","Steven","Max"};
int [] scores = member.getScores(friendIDs);
for (int i = 0; i < scores.length; i++)
System.out.println(friendIDs[i]+" "+scores[i]);
System.out.println("Test 2");
scores = member.getScores10();
for (int i = 0; i < scores.length; i++)
System.out.println(scores[i]);
System.out.println("Test 3");
scores = member.getScoresLast10();
for (int i = 0; i < scores.length; i++)
System.out.println(scores[i]);
member.removeFriend("Bea");
member.addFriend("Eric", -1);
member.addFriend("Abby", -2);
member.addFriend("Jacob", 3);
member.addFriend("Blake", 8);
System.out.println("Test 4");
scores = member.getScores10();
for (int i = 0; i < scores.length; i++)
System.out.println(scores[i]);
System.out.println("Test 5");
scores = member.getScoresLast10();
for (int i = 0; i < scores.length; i++)
System.out.println(scores[i]);
}
}
The output should be
Test 1
Paul 3
Kevin 3
Steven 21
Max 32
Test 2
3
1
4
7
3
21
9
-5
77
32
Test 3
32
77
-5
9
21
3
7
4
1
3
Test 4
3
1
4
7
3
21
9
-5
32
-1
Test 5
8
3
-2
-1
32
-5
9
21
3
7
Your loop for counting down is missing one value to copy:
Wrong:
for (int i = friendsScore.size()-1; i > (friendsScore.size()-10); i--)
This runs for 9 times.
Right:
for (int i = friendsScore.size()-1; i >= (friendsScore.size()-10); i--)
This runs 10 times and copies all 10 values to the array. Note the >= instead of >.
With the first loop the last value of your array will never be set and so defaults to 0 or whatever your compiler might set (I think it is always 0 in java but I'm not sure).

Java array removal gives unexpected results?

The following code is part of a program which takes the values of array ar except for variable z, and copies it onto a different array called ar2. The result should be all the numbers except negative two (19, 1, 17, 17), but currently the result is 19 1 17 17 -2 19 1 17 17 -2 19 1 17 17 -2 19 1 17 17 -2.
public class Second_tiny {
public static void main(String[] args) {
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 0; i < (ar.length); i++) {
if (z > ar[i]) {
z = ar[i];
}
}
// second pass
int[] ar2 = new int[ar.length];
int zero = 0;
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
}
/*
* //2nd pass copy all items except smallest one to 2nd array int[] ar2= new int[ar.length-1]; int curIndex = 0; for (i=0; i<ar.length; i++) { if (ar[i]==z) continue; ar2[curIndex++] =
* ar[i]; }
*/
}
}
}
Java 8 way:
int[] ar = { 19, 1, 17, 17, -2 };
int min = Arrays.stream(ar).min().getAsInt();
int[] ar2 = Arrays.stream(ar).filter(s -> s!=min).toArray();
System.out.println(Arrays.toString(ar2));
You're printing out your original array 4 times in this block:
for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
}
That block should be outside of your loop, and should reference ar2 instead of ar.
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
}
for (int i = 0; i < ar2.length; i++) {
System.out.println(ar2[i]);
}
This will give you the following result:
19
1
17
17
0
The last 0 appears because 0 is the default value for ints. Your ar2 array is 5 elements long, and for the last element the default value is never replaced.
You could use Math.min(int, int) to determine your lowest value. Your second array should be one element smaller. I suggest guarding against removing more than one value. And you could use Arrays.toString(int[]) to print the second array. Something like,
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 1; i < ar.length; i++) {
z = Math.min(z, ar[i]);
}
// second pass
int[] ar2 = new int[ar.length - 1];
boolean first = true;
for (int x = 0; x < ar.length; x++) {
if (ar[x] == z && first) {
first = false;
continue; // If it is equal to z go back to the loop again
}
int y = x - (!first ? 1 : 0);
ar2[y] = ar[x];
}
System.out.println(Arrays.toString(ar2));
Output is
[19, 1, 17, 17]
you code is right mistakenly you have given one extra for loop.i have done comment on that for loop.use the following code u will get the desired output.
public class HelloWorld {
public static void main(String[] args) {
int[] ar = { 19, 1, 17, 17, -2 };
int z = ar[0];
for (int i = 0; i < (ar.length); i++) {
if (z > ar[i]) {
z = ar[i];
}
}
// second pass
int[] ar2 = new int[ar.length];
int zero = 0,i=0;
for (int x = 0; x < (ar.length); x++) {
if (ar[x] == z) {
continue; // If it is equal to z go back to the loop again
}
ar2[zero++] = ar[x];
// for (int i = 0; i < ar.length; i++) {
System.out.println(ar[i]);
i++;
// }
/*
* //2nd pass copy all items except smallest one to 2nd array int[] ar2= new int[ar.length-1]; int curIndex = 0; for (i=0; i<ar.length; i++) { if (ar[i]==z) continue; ar2[curIndex++] =
* ar[i]; }
*/
}
}
}
output is:
19
1
17
17

Categories

Resources