How to print the following sequence, while satisfying these conditions - java

This was actually an interview question. I had to print the following using Java:
9
9 8 9
9 8 7 8 9
9 8 7 6 7 8 9
. . .
. . .
During the interview, I wrote an embarrassing piece of code, but it worked nonetheless - using an outer loop, two inner loops (one for the decrementing sequence and one for the incrementing sequence!) and a ton of variables. One of the variables was the length of each row.
The interviewer asked me to try and rewrite it using
just one outer and one inner loop
without the row length variable.
Note: After looking at the answers, I think the interviewer didn't really mean the second condition. He might have just wanted me to simplify my code and the second point just bumbled out of his mouth.
So, later back home, I arrived at this:
int rowCnt = 5;
for(int i = 1; i <= rowCnt; i++)
{
int val = 9;
int delta = -1;
int rowLen = i * 2 - 1;
for(int j = 1; j <= rowLen; j++)
{
System.out.print(val + " ");
val += delta;
if(j >= rowLen / 2) delta = 1;
}
System.out.println();
}
Here, I am using just one inner loop. I'm using a delta value to determine whether increment or decrement happens. For each row, I compare the current index to the midpoint of the row and change the delta.
I satisfied the first condition - just one inner loop. But I am not able to do it without using the row length.
How can we print this without finding out the row length?
Many answers were acceptable, But I had to choose one, and picked the one that was simplest to understand for me.

They probably wanted to hear the word 'recursion'.
Here's a recursive solution that doesn't need length:
countDownInMiddle("", 9, "");
private static void countDownInMiddle(String start, int n, String end) {
if (n < 0) {
return;
}
System.out.println(start + n + end);
countDownInMiddle(start + n, n - 1, n + end);
}

How about:
int start = 9;
for (int i = 0; i <= start; i++) {
StringBuilder sb = new StringBuilder((start - i) + " ");
for (int j = start - i; j < start; j++) {
sb.insert(0, (j + 1) + " ");
sb.append((j + 1) + " ");
}
System.out.println(sb.toString());
}

This is simple PHP, hope logic is clear and easily portable to Java:
$rowCount = 10;
$startNum = 9;
for ($idx =0; $idx <$rowCount; $idx ++) {
for ($jdx=0; $jdx < (2*$idx +1); $jdx++) {
if ($idx < $jdx)
echo $startNum -(2*$idx) + $jdx.' ';
else
echo $startNum - $jdx.' ';
}
echo '<br/>';
}

public class Pyramid {
public static void main(String[] args) {
int start = 9;
String left = "";
String right = "";
for (int i=start; i>=0; i--) {
System.out.println(left+i+right);
left = left+i;
right = i+right;
}
}
}
Sample output:
9
989
98789
9876789
987656789
98765456789
9876543456789
987654323456789
98765432123456789
9876543210123456789
This iterative solution is equivalent to the recursive solution. I would prefer to use iteration over recursion since the extra stack memory needed by the recursive solution could be huge when the number of rows grows big.

My non-recursive solution:
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 2*i+1; j++)
System.out.print((Math.abs(j - i) + 9 - i) + " ");
System.out.println();
}

Related

Using return vs While(condition) methods To Break Loops

I'm doing a little google interview question. Find the pair of numbers in a loop that add up to the number given. I found the numbers 2 and 6 that make up 8 so I say match = true so that the while loop stops, however it still proceeds until it finds the second which is 6 and 2 however, those numbers I have already found just the other way around and I had expected my loop to break as my if statement states if there is any 2 numbers that give the sum, match = true therefore terminating the loop, I guess I am wrong though.
However, if I get rid of the while statement and just return; once a match is found it breaks without looking for the second match (which I want it to).
Why is this happening, the logic of both seems the exact same to me.
Using the while(condition) Method
public class Main {
public static void main(String[]args){
int[] list = new int[]{1,2,1,1,1,6};
boolean match = false;
int sumNeeded = 8;
while(!match){
for(int i = 0; i < list.length; i ++){
for(int j = (list.length -1); j >= 0; j --){
if(list[i] != list[j]){
if(list[i] + list[j] == sumNeeded){
System.out.println("The numbers are = " + list[i] + " & " + list[j]);
match = true;
}
}
}
}
}
}
}
Using return
public class Main {
public static void main(String[]args){
int[] list = new int[]{1,2,1,1,1,6};
int sumNeeded = 8;
for(int i = 0; i < list.length; i ++){
for(int j = (list.length -1); j >= 0; j --){
if(list[i] != list[j]){
if(list[i] + list[j] == sumNeeded){
System.out.println("The numbers are = " + list[i] + " & " + list[j]);
return;
}
}
}
}
}
}
In your while-loop implementation, if the array doesn't have the desired pair at all it would result in an infinite loop. There is no need for the while statement in your solution.
After you enter into the while loop, you look for all the possible pairs in the array and then check for their sum. If it equals the desired sum, you make the boolean variable match as true.
But, until the nested for loop is completely executed (i.e., all the possible pairs are checked) we do not check for the while condition. The entire nested for loop is executed in one iteration of the while loop. Then, the while loop condition is checked again.
As by the end of the first iteration of the while loop all the possible pairs are accounted for, there is no need for a while loop.
Moreover, there are other logical errors in your implementation. The correct brute-force implementation is as follows:
public class Main {
public static void main(String[]args){
int[] list = new int[]{1,2,1,1,1,6};
boolean match = false;
int sumNeeded = 8;
for(int i = 0; i < list.length; i ++){
for(int j = (list.length -1); j > i; j --){
if(list[i] + list[j] == sumNeeded){
System.out.println("The numbers are = " + list[i] + " & " + list[j]);
return;
}
}
}
}
}
The inner-for loop is modified to reduce the double-counting of the unordered pairs. Whenever a match is found and printed, we exit the function.
You may also add a break statement inside the while loop in your initial implementation.
if(match == true) {
break;
}
The while condition continues to execute the first and second for-loop until it's finished where as with return it stops execution entirely from the first and second loop.
To fix the while loop you could use a label and then break from that.
firstLoop:
for(int i = 0; i < list.length; i ++) {
match = true;
break firstLoop;

Recursion java - differently for loop does not understand how to work

I understand the principle of recursion and code but do not understand the loop for,Why variables are in the same line, we can explain how the loop works?
this line:
for (int i = digit, j = 1; i >= 1; i--, j++)
The code:
public static boolean hasSubSeries(int[] arr, int digit) {
return hasSubSeriesHelper(arr, arr.length, digit);
}
public static boolean hasSubSeriesHelper(int[] arr, int size, int digit) {
if (size == 0)
return false;
for (int i = digit, j = 1; i >= 1; i--, j++) {
if (arr[size - j] != i)
return hasSubSeriesHelper(arr, size - 1, digit);
}
return true;
}
thank's
The structure of the for loop is as follows:
for( starting conditions; verification at each loop; action at end of loop)
In your specific case:
for (int i = digit, j = 1; i >= 1; i--, j++)
Starting conditions:
A variable i which is equal to the value contained in the variable digits that is given at the start of the function hasSubSeriesHelper(int[] arr, int size, int digit).
A variable j which starts at 1.
Verification at each loop:
Once each loop is completed we will check this, if it is True, we keep on looping, if not we exit the loop.
We check to see if i declared at the start is greater than or equal to 1, if it is we keep on looping, if not we stop.
Action at end of loop:
We do two actions i-- which decreases the value of i by 1 and j++ which increases the value of j by 1.
To summarise you could translate it to a while loop if you prefer:
int i = digit;
int j = 1;
while ( i >= 1 ) {
// the code inside the for loop goes here
i--;
j++;
}
Note that the actions at the end happen inside the loop whilst the starting condditions go before the loop.
That should also clarify why you can have various declarations in the same line as long as they are of the same type.
You have three parts in a for loop
N°1 : Initialization of variable(s)
N°2 : Boolean expression evaluated to continue/stop looping
N°3 : Changes operated on variables
1
You may have multiple initialization in the first part, as long as the type stay the same, the following is entirely possible :
We declare and instantiate three variables within the first part of our for declaration.
for(int i = 2, j = 2*i, k = 4*j ; i < 3 ; i++) {
System.out.println(i + " " + j + " " + k); // 2 4 16
}

Count to x amount of numbers then stop in Java?

I am doing a task in my Java class and I am stuck on one part for a week now. I have had all possible errors and infinite loops.
I am trying to display numbers in sequence of 4 and display only 500 numbers.
The code below shows what I have tried:
int add4 = 1;
int count500 = 1;
while (count500 <= 500)
{
if (count500 == 101)
{
System.out.print(add4);
}
else
{
System.out.print(add4 + "," + "");
}
add4 = add4 + 4;
}
Also I am stuck on the lucas sequence numbers.I dont even know where to start with that. I would appreciate your help with those questions.
The simplest way to print the sequence you want would be a for loop and print a function of the loop variable
System.out.print(1);
for (int i = 1; i < 500; ++i) {
System.out.print("," + (4*i+1));
}
This will also avoid trailing commas
Shortest way will be:
for(int i = 1, j = 1; i <= 500; i += 1, j += 4)
System.out.print("i = " + i + " j = " + j);
Refactor to while (count500++ <= 500). Then the loop will terminate correctly.
That said, I'd prefer something on the lines of
for (int i = 0; i < /*ToDo - limit*/; ++i){
System.out.print(i * 4); // ToDo - all your special whitespace.
}
since then you're operating on the iterating variable which will reduce the potential for bugs, such as the one that you have.
If you are not incrementing the value of count500 then how it will reach 500 ?
Add count500++ at the end of the loop
Your stuck in the loop because your precondition is count500 <= 500
The problem is you never change the value of count500.
I see two ways for you to get out of this infinte loop:
1.- Increment it in in your loop:
int add4 = 1;
int count500 = 1;
while (count500 <= 500)
{
if (count500 ==101)
{
System.out.print(add4);
}
else
{
System.out.print (add4 +"," +"");
}
add4 =add4 + 4;
count500++;
}
2.- Do it right in your while:
while (count500++ <= 500)
In bove cases he will run the loop 500 times.
Here ya go:
int add4 = 0;
for (int i = 0; i > 500; i += 1) {
System.out.println(add4);
add4 += 4;
}
Let's break that down.
First, we're initialising the variable add4 at zero, which later, in the for loop, increases by 4 directly after being printed.
Then, since you only want to print add4 out 500 times, you declare a for loop, which initialises integer i at zero (int i = 0), then tells the loop to continue while i is less than 500 (i > 500), and finally tells i to increase by one each time you go through the loop (i += 1).
Within the loop, add4 is being printed out, then being incremented by four. The last value printed out should be 2000, but the value of add4 at the end should actually be 2004.
Hope that helps.
I'm not exactly sure what you are trying to do but try this:
public class TestSequence {
static final int AMOUNT_NEEDED = 500;
static final int INCREMENT = 4;
static final int UPPER_LIMIT = AMOUNT_NEEDED * INCREMENT;
public static void main(String[] args) {
for( int numberMod4 =0; numberMod4< UPPER_LIMIT; numberMod4+=INCREMENT)
System.out.println(numberMod4);}
}

finding longest sequence of consecutive numbers

Problem H (Longest Natural Successors):
Two consecutive integers are natural successors if the second is the successor of the first in the sequence of natural numbers (1 and 2 are natural successors). Write a program that reads a number N followed by N integers, and then prints the length of the longest sequence of consecutive natural successors.
Example:
Input 7 2 3 5 6 7 9 10 Output 3 this is my code so far and i have no idea why it does not work
import java.util.Scanner;
public class Conse {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int[] array = new int[x];
for (int i = 0; i < array.length; i++) {
array[i] = scan.nextInt();
}
System.out.println(array(array));
}
public static int array(int[] array) {
int count = 0, temp = 0;
for (int i = 0; i < array.length; i++) {
count = 0;
for (int j = i, k = i + 1; j < array.length - 1; j++, k++) {
if (Math.abs(array[j] - array[k]) == 1) {
count++;
} else {
if (temp <= count) {
temp = count;
}
break;
}
}
}
return temp + 1;
}
}
Why two loops? What about
public static int array(final int[] array) {
int lastNo = -100;
int maxConsecutiveNumbers = 0;
int currentConsecutiveNumbers = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == lastNo + 1) {
currentConsecutiveNumbers++;
maxConsecutiveNumbers = Math.max(maxConsecutiveNumbers,
currentConsecutiveNumbers);
} else {
currentConsecutiveNumbers = 1;
}
lastNo = array[i];
}
return Math.max(maxConsecutiveNumbers, currentConsecutiveNumbers);
}
This seems to work:
public static int longestConsecutive(int[] array) {
int longest = 0;
// For each possible start
for (int i = 0; i < array.length; i++) {
// Count consecutive.
for (int j = i + 1; j < array.length; j++) {
// This one consecutive to last?
if (Math.abs(array[j] - array[j - 1]) == 1) {
// Is it longer?
if (j - i > longest) {
// Yup! Remember it.
longest = j - i;
}
} else {
// Start again.
break;
}
}
}
return longest + 1;
}
public void test() {
int[] a = new int[]{7, 2, 3, 5, 6, 7, 9, 10};
System.out.println("Longest: " + Arrays.toString(a) + "=" + longestConsecutive(a));
}
prints
Longest: [7, 2, 3, 5, 6, 7, 9, 10]=3
Since your question has "Problem H" associated with it, I'm assuming you are just learning. Simpler is always better, so it usually pays to break it down into "what has to be done" before starting on a particular road by writing code that approaches the problem with "how can this be done."
In this case, you may be over-complicating things with arrays. A number is a natural successor if it is one greater than the previous number. If this is true, increment the count of the current sequence. If not, we're starting a new sequence. If the current sequence length is greater than the maximum sequence length we've seen, set the max sequence length to the current sequence length. No arrays needed - you only need to compare two numbers (current and last numbers read).
For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int maxSequenceLen = 0; // longest sequence ever
int curSequenceLen = 0; // when starting new sequence, reset to 1 (count the reset #)
int last = 0;
for(int i = 0; i < N; i++) {
int cur = scan.nextInt();
if ((last+1) == cur){
++curSequenceLen;
}
else{
curSequenceLen = 1;
}
if (curSequenceLen > maxSequenceLen){
maxSequenceLen = curSequenceLen;
}
last = cur;
}
System.out.println(maxSequenceLen);
Caveat: I'm answering this on a computer that does not have my Java development environment on it, so the code is untested.
I'm not sure I understand this question correctly. The answer's written here assumes that the the natural successors occur contiguously. But if this is not the same then the solution here might not give the correct answer.
Suppose instead of [7 2 3 5 6 7 9 10] the input was [7 2 6 3 7 5 6 9 10] then the answer becomes 2 while the natural successor [5 6 7] is present in the array.
If the input is not sorted we'll have to use a different approach. Like using HashSet
Load the entire array into a HashSet which removes duplicates.
Pick the first value from the HashSet and assigned it to start and end and remove it from the set.
Now decrements start and check if it is present in the HashSet and continue till a particular value for start is not present int the HashSetwhile removing the value being searched from the set.
Do the same for end except that you will have to increase the value of end for each iteration.
We now have to continuous range from start to end present in the set and whose range is current_Max = end - start + 1
In each iteration we keep track of this current_Max to arrive at the longest natural successor for the entire array.
And since HashSet supports Add, Remove, Update in O(1) time. This algorithm will run in O(n) time, where n is the length of the input array.
The code for this approach in C# can be found here

Problem with output, Java

I need for my output to be the first 100 pentagonal numbers, ten per row , counting in succession. As it stands my output just repeats itself, i am sure this is a simple answer but i cant seem to come up with it. This was homework and already graded but i would like to figure it out for me to learn. Thanks in advance for any input and help.
package chapter_5;
/**
*
* #author jason
*/
public class Five_One {
public static void main(String[] args) {
for (int k = 1; k < 11; k++) {
for (int n = 1; n < 11; n++) {
System.out.print(getPentagonalNumber(n)+ "\t");
}
System.out.println();
}
}
public static int getPentagonalNumber(int n) {
return n * (3 * n - 1) / 2;
}
}
you are repeatedly calling getPentagonalNumber() with numbers in range [1,10], instead of calling numbers in increasing range. can be solved by adding 10*k [and running k from 0 to 10 instead 1 to 11]
public static void main(String[] args) {
for (int k =0; k < 10; k++) { //range is [0,10) instead [1,11)
for (int n = 1; n < 11; n++) {
System.out.print(getPentagonalNumber((10*k)+n)+ "\t"); //10*k + n instead of n
}
System.out.println();
}
}
It should be:
System.out.print(getPentagonalNumber((k-1) * 10 + n) + "\t");
because if not, you are writing the first 10 pentagonal numbers, ten times.
In any case, I'd rather try to focus on creating a code that is as easy to read/maintain as possible, so I'd use only one loop:
for (int i = 0; i < 100; i++) {
System.out.print(getPentagonalNumber(i + 1) + "\t");
if (i % 10 == 0) {
System.out.println();
}
}
If you need the first 100 pentagonal numbers, you only need one for-loop going from 1 to 100.
Hope this helps.
Your output contains
getPentagonalNumber(n)
where n is the column number. Thus each row is the same.
You'll have to incorporate the row number k also in you calculation:
getPentagonalNumber((k-1) * 10 + n)
i.e. from row to row your index is increased by 10.

Categories