Printing a sideways triangle in java - java

I'm trying to print a sideways triangle in java. If the user enters 5, the output should be:
*
***
*****
***
*
If the user enters 6, the output should be:
*
***
*****
*****
***
*
I've gotten it to work for the case when the user enters 5, 3, or 1 but my code seems to work for those three cases only. I was wondering if anyone could help me get my code working for more cases.
Here it is:
public void printArrow( int n )
{ int asterisks = 1;
for ( int i = 0; i <= n/2; i++ )
{
for ( int j = i; j < asterisks; j++ )
{
System.out.print( "*" );
}
asterisks += 3;
System.out.println();
}
asterisks = asterisks / 2 - 2;
for ( int i = 0; i < n/2; i++ )
{
for ( int k = i; k < asterisks; k++ )
{
System.out.print( "*" );
}
if ( i == 1 )
{
System.out.print( "*" );
}
asterisks -= 2;
System.out.println();
}
}

It's much easier to solve this using recursion:
static String triangle(int n, String s) {
return
n == 0 ? "" :
n == 1 ? s :
s
+
triangle(n - 2, "**" + s)
+
s
;
}
public static void main(String args[]) {
System.out.println(triangle(6, "*\n"));
}
The structure of the triangle is self-evident:
n == 0? No line!
n == 1? One line!
Otherwise? Two lines sandwiching n - 2 lines! (which are longer!)

Alright Will I'll bite
So the goal is to print out a triangle of stars. Well we are going to need a loop of some kind, probably with another internal loop. And we know that it's going to be symmetric as it's a triangle.
so I'd start with printing the fist half:
function triangle( input )
i <- 1
while i < input do
for j from 1 to i do
print "*"
end for
i <- i + 2
print "\n"
end while
After that we'd need to deal with the second half of the triangle which, because we have already walked i up to the input value means we can just walk it back down.
if i > input then i <- i - 2
while i > 0 do
for j from 1 to i do
print "*"
end for
i <- i - 2
print "\n"
end while
end function triangle
the little trick in it that almost caught me is the subtraction of two before the second while, if you don't do this you'll get the wrong answer. I'll leave figuring out why up to you. If there is confusing in the pseudocode notation please ask.

double middle = ((double) lines) / 2;
int asterisks = 1;
for (int i = 1; i <= lines; i ++){
for (int k = 0; k < asterisks; k ++) {
System.out.print("*");
}
if (i < middle) {
asterisks += 2;
} else if (i > middle){
asterisks -= 2;
}
System.out.println();
}
Explaining:
lines is the input number (3,4,5,6,7, etc)
get the middle row as a double. I.e. for odd numbers it will be x.5
the loop is for as many lines as the input is
on each line print as many asterisk as there are in the asterisks variable
on each iteration either increase the number of asterisk by 2, if the line is before the middle, or decrease it, if after. This means that if it is equal, nothing happens - i.e. the same row has the same number of asterisk. And it can't be equal for odd numbers.

Related

print numbers from 1 to 1000 digit number - interview question

I had an interview and I've been asked to print numbers from 1 to a 1000 digit number -
1,
2,
3,
.
.
.
.,
999999999999999999999999999999999999999999999999........
I couldn't solve it but I'm still looking for the best way to do it, because obviously, you cant use integers or floats in a case like this and because it's a job interview I couldn't use any libraries that can handle it.
Can anyone think of a good solution? preferably in Java/pseudocode.
I had an interview and I've been asked to print numbers from 1 to a 1000 digit number
I guess the kind of answer they expected you to give is:
"We need to print the numbers from 1 to 10^1000-1. Last year, $80e9 worth of processors were sold worldwide [1], even if one processor per dollar had been sold and each processor was a thousand times faster than the fastest of them all [2] and only one instruction was used to print each number and all these processors had been produced during the last 1000 years, still: 1e1000 / (80e9 - 1000 - 8.4e9 - 1000) > 1e973 seconds to print all the numbers. That is 10e956 billion years."
Anyway, if you wish wait:
BigInteger n = BigInteger.ONE;
BigInteger last = BigInteger.TEN.pow(1000);
while(n.compareTo(last) < 0) {
System.out.println(n);
n = n.add(BigInteger.ONE);
}
Assuming only System.out.print is able to use (String is a library, see [3]), a possible solution without copy over and over again strings, and with the expected output could be:
static void printDigits(int n) {
ds(0, n, new byte[n]);
}
static void ds(int p, int k, byte[] d) {
if (p < d.length) { // if more digits to print
for (byte i = 0; i < 10; i++) { // from digit 0 to 9
d[p] = i; // set at this position
ds(p + 1, i == 0 ? k : (p < k ? p : k), d); // populate next storing first non-zero
}
} else {
if(k < d.length) { // if is not zero
if(k < d.length - 1 || d[d.length - 1] != 1) // if is not one
System.out.print(", "); // print separator
for(int i = k; i < d.length; i++) // for each digit
System.out.print((char)('0' + d[i])); // print
}
}
}
then, for printDigits(5) the output is
1, 2, 3, 4, ..., 99999
[1] https://epsnews.com/2020/09/14/total-microprocessor-sales-to-edge-slightly-higher-in-2020/
[2] https://en.wikipedia.org/wiki/Clock_rate
[3] https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Using recursion (if only to print):
void digits(int count) {
if (count < 0) throw new IllegalArgumentException("invalid count: " + count);
digits(count, "");
}
void digits(int count, String text) {
if (count == 0) {
System.out.println(text);
} else {
for (var i = 0; i < 10; i++) {
if (i == 0 && text.isEmpty()) {
digits(count-1, text);
} else {
digits(count-1, text+i);
}
}
}
}

Printing a unique triangle of characters in java

I need to print a triangle of characters:
0
1 0
1 0 1
0 1 0 1
The code I have prints it as this:
0
1 0
0 1 0
1 0 1 0
I can print it alternating, but when I try to change from alternating to unique characters I run into issues.
public static void main(String[] args) {
//mod even = 0, mod 1 = odd
int height;
int zero = 0;
int one = 1;
height = 4;
for(int i=1; i<=height; i++) {
for(int j=1; j<=i; j++) {
if ((j % 2) == 1) {
System.out.print((i % 2 == 1) ? zero : one);
} else {
System.out.print((i % 2 == 1) ? one : zero);
}
}
System.out.println();
}
}
I've tried adding in the if statement a scenario such as
if ((j % 2) == 1 && i == height){
System.out.print((i % 2 == 1) ? one : zero);
}
to get the last line to print starting with one, but it gets buggy and affects all lines. Any suggestions?
private static void triangle(int height) {
int valueToPrintNext = 0;
for(int i = 0; i < height; i++)
{
for(int j = -1; j < i; j++)
{
System.out.print(valueToPrintNext + " ");
valueToPrintNext = valueToPrintNext==0 ? 1 : 0;
}
System.out.println();
}
}
Main:
public static void main( String[] args )
{
triangle(6);
}
Output:
0
1 0
1 0 1
0 1 0 1
0 1 0 1 0
1 0 1 0 1 0
First of all: you're a programmer now. Programmers start counting from 0, not 1. PARTICULARLY in our for(){} loops. You're almost certainly a student, so just keep working at it.
What you're printing is basically "1 0 1 0" with newLines sprinkled in... so that's exactly how I'm going to do it.
This shows you that there are at least two different approaches to solving this problem. Bonus credit for anyone who comes up with a 3rd one (no not really).
Lets do a little numeric analysis to figure out the math on the total character count given a particular number of lines...
1 = 2 "1\n"
2 = 6 "1\n0 1\n"
3 = 12 "1\n0 1\n0 1 0\n"
4 = 20
5 = 30
6 = 42
n = n^2 + n
Okay, so now we write that up as a fairly trivial function. Lots of little functions is always easier to write AND TEST than a few big ones. Small functions good. Big functions bad.
private int getEndOfLinePosition(int lines) {
return lines * lines + lines;
}
And here we have the code which handles the aforementioned testing. Unit tests are awesome. Many people encourage you to write your unit tests BEFORE the code your testing. A good idea, but one I have to work at to follow. I like JUnit 5.
// imports go before your class at the top of the file
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
#Test
public void eolTest() {
int correctLengths[] = {2, 6, 12, 20, 30, 42};
for (int i = 0; i < 6; ++i) {
Assertions.assertEquals(correctLengths[i], getEndOfLinePosition(i + 1));
}
}
We'll build two functions, one to build the ones and zeros, and the other two sprinkle in the new lines. And we'll need a 'main' to glue 'em together.
void main() {
int height = 4;
StringBuffer onesAndZeros = buildOnesAndZeros(height);
addNewlines(onesAndZeros, height);
System.out.print(onesAndZeros);
}
There shouldn't be any surprises there... except perhaps that I'm using a StringBuffer rather than a String. String is immutable in Java, StringBuffer is expressly intended to be messed with, and mess with it we shall. Also, using print instead of println: our return will be built into the string.
private StringBuffer buildOnesAndZeroes(int height) {
int stringLength = getEndOfLinePosition(height);
StringBuffer buffer = new StringBuffer(stringLength);
char nextChar = '0';
for (int i = 0; i < stringLength; i += 2) {
buffer.append(nextChar);
buffer.append(' ');
nextChar = i % 2 == 1 ? "1" : "0";
}
return buffer;
}
The expression to determine nextChar might be backwards, but that should be easy to detect and fix. I may have even gotten it backwards on purpose just to leave you a bug to squish.
String addNewLines(StringBuffer onesAndZeros, int height) {
for (int i = 0; i < height; ++i) {
int currentEnd = getEndOfLinePosition(i);
onesAndZeros.setCharAt(curentEnd - 1, '\n');
}
}
Wrap all that in a class, and Bob's your uncle. Where the hell does that expression come from anyway? I mean... England, yeah, but why?!

Trying to properly print an array in Java

I am new to Programming so bear with me if I do not properly present my issue. I have an assignment to create a program to assign integer values 1-25 to a 25 element integer array. I need to print the array as five separate lines with each line containing 5 elements separated by commas. The last element does not have a comma following it. The final output should be as follows:
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
The code that I came up with comes close, but it's not quite right. The code that I came up with is:
public class Test2 {
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
System.out.print(numbers[i] + ",");
if (i % 5 == 0 && i > 0)
System.out.println();
}
}
}
The printout that I get from my code is as follows:
1,2,3,4,5,6,
7,8,9,10,11,
12,13,14,15,16,
17,18,19,20,21,
22,23,24,25,
I am not sure why I am getting 1-6 on the first line as well as how to remove the comma at the end of each line. Any help pointing out my errors would be appreciated.
The error is that you are checking if int i is divisible by 5 (i % 5), not numbers[i] (numbers[i] % 5). This way, your code prints:
number 1 when i = 0,
number 2 when i = 1,
number 3 when i = 2,
number 4 when i = 3,
number 5 when i = 4,
number 6 when i = 5
and finally prints line break.
The correct code is:
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i]=i+1;
System.out.print(numbers[i]);
if (numbers[i] % 5 == 0 && i > 0) {
System.out.println();
} else {
System.out.print(",");
}
}
The above code will print (as intended):
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
You're getting 6 numbers on the first line, because you start counting at i=0, and only print the newline once i=5; at which point the number you've just printed is 6, not 5 - you're printing i+1 in each iteration.
If you made your logic such that it printed EITHER a comma OR a newline but not both, you'd get rid of the commas at the ends of the lines.
You're close. Very close.
Consider what your condition is checking - you want to inspect a value i, and want to stop when that particular value is divisible by 5 but is nonzero.
The problem is that you have the wrong value - i isn't what you want, but numbers[i]. The reason: each number in numbers[i] is offset of i by 1.
What you want to do is check if numbers[i] is divisible by 5. You still need to check for a nonzero i, though.
if(numbers[i] % 5 == 0 && i > 0) {
System.out.println(numbers[i]);
} else {
System.out.print(numbers[i] + ",");
}
Replace
if (i % 5 == 0 && i > 0)
with
if (i % 5 == 4)

Sum of factorials

So I need to output a sum of factorials like 1!+2!...+n!=sum I found a way to get a single factorial but I don't know how to sum them together. This is my attempt at doing so:
System.out.println("Ievadiet ciparu");
Scanner in = new Scanner(System.in);
n = in.nextInt();
if ( n < 0 )
System.out.println("Ciparam jabut pozitivam.");
else
{
while (x>2){
for ( c = 1 ; c <= n ; c++ )
fact = fact*c;
sum=sum+fact;
n=n-1;
if (n==0) break;
}
System.out.println("Faktorialu summa "+sum);
Rather than have a loop 1-n and calculate each factorial elsewhere, I would accumulate the sum as you calculate the factorials - ie have two local variables; one for factorial and one for the sum:
long factorial = 1, sum = 0;
for (int i = 1; i <= n; i++) {
factorial *= i;
sum += factorial;
}
When tested with n = 5, sum is 153, which is correct: 1 + 2 + 6 + 24 + 120
Your problem was that the sum was outside the loop - you just needed braces like here.
Also, your while loop condition x < 2 will never change, so either the loop will never execute (if x > 1) or the loop will never terminate, because x is not changed within the loop.
hmmm my search for finding a recursive(via recursive method calling) version of these code still getting nowhere
`public static long factorialSum(long n){
long x = n;
for(int i = 1; i < n; i++){
x = (n-i)*(1+x);
}
return x;
}`
if you just look at the problem more closely you'll see you can do it in linear time, the trick is in (n-1)! + n! = (n-1)!*(1 + n), to understand this more deeply i recommend add (n-2)! just to see how it grows.

A graphic representation of occurence of numbers and letters with asteriks

DISCLAIMER: THIS IS PART OF A HOMEWORK ASSIGNMENT
So i have created an array with the the count of each letter. It would look something like this:
Array charCount
charCount[0] = 10
charCount[1] = 6
charCount[2] = 4
I know that 0 = a, 1 = b etc.
Now I want to print these results to a graphic representation using asteriks. For example:
*
*
*
*
*
**
**
**
***
***
***
ABC
I found this rather difficult and don't really understand how to do this.
- I've made a function to check the max value of my array.
for (int i = 0; i < charCount.length; i++) {
if (letterCount[i] > maxInt) {
maxInt = charCount[i];
}
}
Then I've made a for loop to check if there are any matches.
My next part of code is:
for (int i = 0; i < letterCount.length; i++ ) {
for (int j = 0; j <= maxInt; j++) {
if (letterCount[i] == maxInt) {
System.out.println("*");
} if (letterCount[i] == maxInt - j ) {
System.out.println("*");
} if (letterCount[i] != maxInt ) {
System.out.println(" ");
}
}
But here it where I got stuck.
How do i print asteriks all the way down and next to each other? Should I work with spaces?
How do i know when to stop printing? Does my maxInt - j makes sense?
Can someone point my in the right direction?
I have to come up with a solution using for loops and arrays, So i cant use any fancy methods yet :)
Thank you :)
Imagine you wanna draw this like a bar graph to a grid, which has coordinates, similar to what you did in school with x and y coordinates.
To stay with your example, each y coordinate represents the index of your array, e.g. the specific letter, where the x - coordinate the amount.
Since those numbers may get quite large, it's, like you saw, not best practice to map +1 on the x-coordinate to +1 letter.
Therefore you need to determine the size of your diagram, let's say it shall be 10 letters wide:
y <- 10
^
a|**********
b|**********
c|**********
-------------> x
12345 ...10
Now it's important that the occurences of the letters relative to each other are represented correctly by those *-bars, that means the letter which occurs the most could be shown with a bar exactly as long as you draw the x-coordinate, in this case 10.
Lets use this as an example dataset
0 := 10
1 := 6
2 := 4
3 := 14
If the x-coordinate is 10 * long, the amount from entry 3 (highest in the array) is 14 and needs to be 10 * long. With this information you can calculate the factor by dividing 10(x-length) / 14(biggest amount) ~= 0.71 (the factor)
This factor you apply to all the numbers to get number of stars to draw.
Here as an example in java:
int xLength = 10;
int[] charCount = new int[5];
charCount[0] = 10;
charCount[1] = 4;
charCount[2] = 7;
charCount[3] = 14;
charCount[4] = 1;
// determine the biggest value:
int biggest = 0;
for(int n:charCount) {
if(n>biggest)
biggest = n;
}
System.out.println("Biggest no: " + biggest);
double factor = (double)xLength / (double)biggest;
System.out.println("Using factor: " + factor);
for(int i = 0; i < charCount.length; i++) {
System.out.print("no " + i + ":");
for(int j = 0; j < charCount[i] * factor; j++) {
System.out.print("*");
}
System.out.println();
}
This will output:
Biggest no: 14
Using factor: 0.7142857142857143
no 0:********
no 1:***
no 2:*****
no 3:**********
no 4:*
EDIT:
If you want to print the bars vertically (on the y-choordinate), or turn it any other way, store the bars in a grid, for example with a String[][] array, where arr[2][3] would be y-coordinate 2 and x-coordinate 3. Then you can calculate with the factor above and the maximum height of the chart whether or not a specific point / coordinate should be filled with a "*" or a " " (nothing):
// make a grid to draw the chart
// the height is the the number we defined as maximum height (xLength)
// and the width is one column for every char (charCount.length):
String[][] grid = new String[charCount.length][xLength];
// initialize the grid with spaces:
for(int x = 0; x < grid.length; x++) {
for(int y = 0; y < grid[x].length; y++) {
grid[x][y] = " ";
}
}
// We will go through the grid column by column:
for(int x = 0; x < grid.length; x++) {
// this will be called once for every char
// so just replace spaces in the grid in this column
// by "*" if it's a row (value of y) <= the amount
// of chars times the factor
for(int y = 0; y < grid[x].length; y++) {
if(y <= charCount[x] * factor) {
grid[x][y] = "*";
}
}
}
// print the grid row by row (think of it upside down, (0,0) is the upper left point
// so we start with the last (the no of elements in the array minus 1, counting from 0)
System.out.println("^");
for(int y = grid[0].length - 1; y >= 0; y--) {
System.out.print("|");
for(int x = 0; x < grid.length; x++) {
System.out.print(grid[x][y]);
}
// finish the line:
System.out.println();
}
// draw the bottom line:
System.out.println("------->");
System.out.println(" abcde");
Added this code just below the code from above, the output will be:
Biggest no: 14
Using factor: 0.7142857142857143
no 0:********
no 1:***
no 2:*****
no 3:**********
no 4:*
^
| *
| *
|* *
|* *
|* **
|* **
|* **
|****
|****
|*****
------->
abcde
If you want to put the amounts left to the y-bar, divide the row number by the factor.
If you want to use the absolute values without scaling up or down (which would fill the screen pretty fast for big numbers), just set the 'xLength' (height of the grid) to the biggest number in the input array.

Categories

Resources