Pyramid Pattern in Java - java

It was so hard to ask such a newbie question on this advanced site. But after so much tries and even loosing my hope i was forced to bring my self here. I am not been able to print the following pattern:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
But with my tiresome efforts i reached the following:
public static void main(String[] args) {
int num = 1;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15 - i; j++) {
System.out.print(" ");
}
for (int k = 0; k <= i; k++) {
System.out.print(num + " ");
}
System.out.println();
}
}
1
1 1
1 1 1
1 1 1 1
1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1

Here ya go
public static void main(String[] args) {
int max = 6;
int padLength = (int) Math.ceil(Math.log10(Math.pow(2, max) + 1)) + 2;
for (int i = 0; i < max; i++) {
for (int j = 1; j < max - i; j++) {
System.out.print(pad(" ", padLength));
}
for (int k = 0; k <= i; k++) {
System.out.print(pad(Math.pow(2, k), padLength));
}
for (int k = i - 1; k >= 0; k--) {
System.out.print(pad(Math.pow(2, k), padLength));
}
System.out.println();
}
}
public static String pad(double d, int l) {
Integer i = (int) d;
return pad(i.toString(), l);
}
public static String pad(String s, int l) {
return String.format("%-" + l + "s", s);
}
Explanation
int padLength = (int) Math.ceil(Math.log10(Math.pow(2, max) + 1)) + 2;
Math.pow(2,max) - Gives me maximal number I will have to display
Math.ceil(Math.log10(number + 1)) - I use this to determine length of string representation of specific number. Please refer to wikipedia to check what logarithm is. I add 1 to skip edge case when number is exact power of 10 e.g. log10(10)->1 (this will never occur in task specified in question, it's just for purity of solution). Ceil just rounds number up.
+2 - minimum gap between two numbers is specified example was 2 spaces long so I just add this
You could use here Integer.toString(((int)Math.pow(2, max))).length()+2 but it's not as pretty :)
return String.format("%-" + l + "s", s);
First I build format string that looks like e.g. %-3s, which means print String with minimum length of 3, padding on the right. Second argument is the String I want to print. Refer to documentation
Running example

I find the other answer very overwhelming and dramatic. You don't need much maths and complexity to solve this problem. This might not be the best code but I think it is easy to understand. Not even an explanation is needed, it is a row by row approach, It's good to keep things simple.
public static void main(String[] args) {
// Init
int row = 0;
int maxRows = 6;
int num = 1;
int indent = maxRows - 1;
// Printing loop
while (row < maxRows) {
// Indent
for (int i = 0; i < indent; ++i)
System.out.print(" ");
// Print nums
for (int i = 0; i < num; ++i)
System.out.printf("%4d", (int) Math.pow(2.0, i));
for (int i = num - 2; i >= 0; --i)
System.out.printf("%4d", (int) Math.pow(2.0, i));
// New line
System.out.println("");
// Adjustments
++row;
--indent;
++num;
}
Output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1

Related

How to improve performance while calculating matrix sum

I was given a task during an interview, where I was given a matrix, now I need to generate another matrix out of it using below formula:
Given matrix A[R][C], generate B[R][C]
val = 0;
for (i = 0; i ≤ xPosition; i += 1) {
for (j = 0; j ≤ yPosition; j += 1) {
val = val + a(i, j);
}
}
B(xPosition,yPosition) = val;
I have come up with below code:
public List<List<Integer>> generate(List<List<Integer>> A) {
List<List<Integer>> top = new ArrayList<>();
for (int i = 0; i < A.size(); i++) {
List<Integer> inner = new ArrayList<>();
for (int j = 0; j < A.get(0).size(); j++) {
inner.add(generateValue(A, i, j));
}
top.add(inner);
}
return top;
}
int generateValue(List<List<Integer>> A, int xPosition, int yPosition) {
int val = 0;
for (int i = 0; i <= xPosition; i++) {
for (int j = 0; j <= yPosition; j++) {
int value = A.get(i).get(j);
val += value;
}
}
return val;
}
Sample input :
1 2 3
4 5 6
Output :
1 3 6
5 12 21
How to improve the performance of this logic?
mathematicaly for your solution in array b,each element is related to it's previous one.
to improve your code / optimise it you need to see this relation.
so for every B[i][j] is related to it's previous element and value from the array A.
below is solution mathematically,
b[i][j] = b[i-1][j] + a[i][0]+a[i][1] + a[i][2]+...+a[i][y-1]
for so if you able to implement this, your code will pass all test cases
i am not a java dev, but if you want code, i can write it for you in python
The key is to think of this as a dynamic programming problem, assuming that we have already calculated B[x][y] for all 0 <= x < i, 0 <= y < j when we go to calculate B[i][j].
B[i][j] contains the sum of all elements in the submatrix of A that starts at 0, 0 and ends at i, j. Thus B[i-1][j] will contain the sum of the all the elements in this submatrix except the ones in the ith row. Similarly, B[i][j-1] will contain the sum of the all the elements in this submatrix except the ones in the jth column. Adding these two together, we get the sum of all the elements in the submatrix except for element A[i][j]. However, while doing this we count all the elements from 0, 0 to i-1, j-1 twice, and we have to subtract their sum (which is B[i-1][j-1]) once so that we only sum them up once in total. Then we add the missing element, A[i][j]. Hence
B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j]
This recursion can now be implemented as a O(RC) dynamic programming algorithm.
To help understand this further, consider the following figure representing the submatrix for which we have to find the sum of the elements. The figure is a matrix C[i][j], where the x, yth element is the number of times we have summed A[x][y]. In terms of C[i][j], our end goal (B[i][j]) is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
B[i-1][j] corresponds to the matrix C[i-1][j], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 0 0 0 0
B[i][j-1] corresponds to the matrix C[i][j-1], which is
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
B[i-1][j] + B[i][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1], which is
2 2 2 2 1
2 2 2 2 1
2 2 2 2 1
1 1 1 1 0
B[i-1][j] + B[i][j-1] - B[i-1][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1] - C[i-1][j-1], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 0
Now B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j] corresponds to
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
which is the same as B[i][j].

Get a collection of positive integers adding up to n

Consider the “sums to n problem:” given a positive integer n, list all the different ways to get a collection of positive integers adding up ton. Assume that we don’t care about order, so 1 + 2 and 2 + 1 are the same possibility.For n= 3, the possibilities are1 + 1 + 1, 1 + 2, 3
import java.util.Scanner;
public class SumsToN {
static void listNumber(int arr[], int n, int i)
{
int MAX_POINT = 3;
if (n == 0)
{
printArray(arr, i);
}
else if(n > 0)
{
for (int k = 1; k <= MAX_POINT; k++)
{
arr[i]= k;
listNumber(arr, n-k, i+1);
}
}
}
static void printArray(int arr[], int m)
{
for (int i = 0; i < m; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
public static void main (String[] args)
{
System.out.print("enter n number: " );
Scanner input = new Scanner(System. in);
int n = input.nextInt();
int size = 100;
int[] arr = new int[size];
System.out.println("list of all the possibilities of "+ n + " are");
listNumber(arr, n, 0);
}
}
My work is slightly incorrect as when i enter n = 5, it does not include for example 1 4
and also it orders are wrong like 1+1+2, not 1+2+1---i.e., "order doesn't matter
Can someone help me with this please?
$ java SumsToN
enter n number: 5
list of all the possibilities of 5 are
1 1 1 1 1
1 1 1 2
1 1 2 1
1 1 3
1 2 1 1
1 2 2
1 3 1
2 1 1 1
2 1 2
2 2 1
2 3
3 1 1
3 2
$ java SumsToN
enter n number: 3
list of all the possibilities of 3 are
1 1 1
1 2
2 1
3

Stuck on making a slight adjustment to a DP algorithm (account for tiebreaker)

Sample input:
45 8 4 10 44 43 12 9 8 2
First number = N
Second number = T
Following T numbers = A set of values
My job is to find the subset where the sum is the highest possible one out of all subsets, that doesn't exceed N. Print that set, and the sum. So, output for that input would be:
2 8 9 12 10 4 sum:45
My issue is, I don't have something to decide between tiebreakers. The tiebreaking factor would be the set with larger amount of elements. So my program prints this:
2 43 sum:45
Here is the code (standard I/O):
int val = reader.nextInt();
int num = reader.nextInt(); // never exceeds 20
int[] cost = new int[20];
int[][] dp = new int[10000][10000];
int[][] path = new int[10000][10000];
for (int i = 0; i < num; i++) {
cost[i] = reader.nextInt();
}
for (int i = 0; i < num; i++) {
for (int j = 0; j <= val; j++) {
if (j < cost[i]) {
dp[i + 1][j] = dp[i][j];
}
else {
if (dp[i][j] < dp[i][j - cost[i]] + cost[i]) {
path[i+1][j] = 1;
dp[i + 1][j] = dp[i][j - cost[i]] + cost[i];
}
else {
dp[i + 1][j] = dp[i][j];
}
}
}
}
int k = val;
for (int i = num; i >= 1; i--) {
if (path[i][k] == 1 && k >= 0) {
System.out.print(cost[i - 1] + " ");
k = k - cost[i - 1];
}
}
System.out.print("sum:" + dp[num][val] + '\n');
You are on the right track with your T x N 2-dimensional array. But you shouldn't be tracking the accumulated cost as the value of each cell, that is already tracked by the 2nd index (j in your case). Instead, track the maximum number of elements you can sum to get to that cost so far. By doing this, you don't even need a path array.
Imagine a scenario where N = 5, T = 4, and the numbers are {4, 1, 1, 3}. The first column would track a 1 in the row j == 4 and 0 everywhere else. The second column would track a 2 in the row j == 5, a 1 in rows j == 4 and j == 1 and 0 everywhere else. You could fill it with something like this (may need some tweaking...):
dp[0][cost[0]] = 1;
for (int i = 1; i < T; i++) {
dp[i][cost[i]] = 1;
for (int j = N - 1; j >= 0; j--) {
if (j >= cost[i] && dp[i-1][j-cost[i]] > 0) {
dp[i][j] = dp[i-1][j-cost[i]] + 1;
}
dp[i][j] = Math.max(dp[i][j], dp[i-1][j]);
}
}
The dp table at the end would look like this:
Sum (j)
5 | 0 2 2 3
4 | 1 1 1 2
3 | 0 0 0 1
2 | 0 0 2 2
1 | 0 1 1 1
0 | 0 0 0 0
______________________________
cost | { 4 1 1 3 }
From this table, you know that the maximum number of elements you can use to sum to 5 is 3. To find out what those elements are, work backwards from dp[3][5]. Since dp[2][5] != dp[3][5], you must have added cost[3] (3) as your third element, so add 3 to your result set. The next value to inspect is dp[2][5 - cost[3]], or dp[2][2]. Compare that to the cell to the left, dp[1][2]. They aren't equal, so you must have added cost[2] as well (if they were equal, that means you didn't add cost[2], and the next cell to inspect would be dp[1][2]). Continue until dp[i][j] == 0 or i == 0 to construct your result set.

Understanding Pyramid numbers in Java

I am studying the Pyramid Numbers in Java which has a code like this.
public class PyramidCharForLup {
public static void main(String[] args) {
int x = 7;
for (int i = 1; i <= x; i++)
{
for (int j = 1; j <= x - i; j++)
System.out.print(" ");
for (int k = i; k >= 1; k--)
System.out.print((k >=10) ?+ k : " " + k);
for (int k = 2; k <=i; k++)
System.out.print((k>= 10) ?+ k : " " + k);
System.out.println();
}
}
}
The output is
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
I chop the code and study it line by line I'm already studying in this line so far.. heheh
So here's the code that I want to ask.
public class PyramidCharForLup {
public static void main(String[] args)
{
int x = 7;
for (int i = 1; i <= x; i++) {
for (int j = 1; j <= x - i; j++)
System.out.print(j);
}
}
}
the output of this is 123456123451234123121 for clarification if you are to arrange
123456 12345 1234 123 12 1
First Question: is i in the code for (int j = 1; j <= x - i; j++) become i= 1234567?
Second Question: from the initialization which is one if increment 1..2..3..5..6..7.. are the increment subtracting the last number from 1234567 like
1234567-1... 123456 - 1 ... 12345 - 1 ... 1234 - 1 ... 123 - 1 ... 12-1...1-0.... till false Am I right?
and that's the reason why i got this output 123456 12345 1234 123 12 1
Your code has two nested loops (one loop runs inside the other). This is what happens:
You set x to 7
You are starting the outer loop, setting i = 1. Since 1 <= 7 the loop is entered.
You are starting the inner loop, setting j = 1. Since 1 <= 6 (7-1 from x - i) the loop is entered.
j (1) is printed.
j is increased with 1 and since 2 is less than 6 the inner loop continues.
j (2) is printed.
This goes on until j is 6.
j (6) is printed.
j is increase by 1 and is now 7 which is not <= 6, so the inner loop exits.
i is increased by one (and is now 2).
The inner loop is entered again, setting j to 1. Since j < 5 (7-2 from x - i) the loop is entered.
11 j (1) is printed.
12 j is increase by one and is now 2. Since 2 < 6 the loop continues.
This goes on until i reaches 7. When i the is increased by 1 it is 8 which is not <= 7 so the outer loop also exists and your program is done.
Your program will count and write the digits from 1..6, then from 1..5 until it reaches 1..1

How do I write a program to output a triangle of numbers in Java?

I need help. My assignment is to write a Java program using nested loops to print out the following output pattern:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
//pattern1
for(int outer=1;outer<=6;outer++) // outer loop controls number of rows
{
for(int inner=1;inner<=outer; inner++) // another loop to control number of numbers in each row.
{
System.out.print(inner);
}
System.out.println(); // move the cursor from the end of the current line to the beggiing to the next line
}
//pattern 2
for(int outer =1; outer<=6 ; outer++) //outer loop controls number of rows
{
//3-1 create spaces before numbers.
for(int space=1; space<=6-outer; space++ ) //group controls number of spaces
{
System.out.print(" ");
}
//3-2 print out real numbers.
for(int inner=1;inner<=outer; inner++) // another loop to control number of numbers in each row.
{
System.out.print(inner);
}
System.out.println();
}
Those two codes are back to back, but I do not understand how I would make the numbers 2 4 8 16 etc show up, and put them back to back.
What's wrong with my code? Is there a better way of doing this in Java?
A simple version with bit shifting and static column size / padding - could be improved by using Math.getExponent() for dynamically repeating spaces and format %3d ...
public static void f(int n) {
for (int i = 0; i < n; i++) {
for (int l = n - i; l > 0; l--) { // padding for symmetry
System.out.print(" ");
}
for (int j = 0; j <= i; j++) { // "left side" of pyramid
System.out.printf("%3d ", 1 << j);
}
for (int k = i - 1; k >= 0; k--) { // "right side" of pyramid
System.out.printf("%3d ", 1 << k);
}
System.out.println();
}
}
Output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
You're going to use a nested loop with an if statement controlling the output.
This code should help you with your formatting. You'll have to figure out how to add the || so that it flips the triangle and how to format your print statements so it looks like that.
int totalWidth = 8;
for (int row = 1; row <= totalWidth; row++) {
for (int col = 1; col <= totalWidth; col++) {
if (col <= totalWidth - row) {
System.out.print(" ");
}else {
System.out.print("*");
}
}
System.out.println();
}
It will output
*
**
***
****
*****
******
*******
********
public class pyramid
public static void f(int n) {
for (int i = 0; i < n; i++) {
for (int l = n - i; l > 0; l--) { // padding for symmetry
System.out.print(" ");
}
for (int j = 0; j <= i; j++) { // "left side" of pyramid
System.out.printf("%3d ", 1 << j);
}
for (int k = i - 1; k >= 0; k--) { // "right side" of pyramid
System.out.printf("%3d ", 1 << k);
}
System.out.println();
}
}

Categories