Fibonacci Sequence printing out all values in an array EDIT - java

Okay my new question is how I can let the array print out all numbers of the segment. At the moment I can input a number and the code will print out the corresponding value in Fibonacci. However, I would like the array to print out all values leading up to the answer. Ex. Input = 7, array prints out 0, 1, 1, 2, 3, 5, 8 instead of just 8
package math;
public class Fibonacci {
public static long getFib(int n) {
long Fibby[] = new long[n+1];
Fibby[0] = 1;
Fibby[1] = 1;
for(int i = 2; i<=n; i++) { //initialize loop
Fibby[i] = Fibby[i-1] + Fibby[i-2];
} // end of for loop
return Fibby[n]; //end method getfib
}
}
And the runner
package math;
Scanner key = new Scanner(System.in);
Fibonacci f = new Fibonacci();
int p;
System.out.println("Fib value : ");
p = key.nextInt();
System.out.println( "Fib Value of "+ p +" :: " + f.getFib(p) );
}
How can this happen? My question has been downsized.

You can't run your main method, because System.out.println() expects a parameter it can print. However, your fib() method returns void, so there is nothing to print. Add a return type to your fib() method, and your error in main() will be resolved. Here's a demonstration of printing the 0th to 12th Fibonacci numbers:
FibonacciRunner.java
public class FibonacciRunner
{
public static void main(String[] args)
{
for(int i = 0; i <= 12; i++)
{
System.out.println(Fibonacci.fib(i));
}
for(int i = 0; i <= 12; i++)
{
System.out.println(Fibonacci.fibList(i));
}
}
}
Fibonacci.java
public class Fibonacci
{
public static long fib(int n)
{
long current = 0;
long next = 1;
for(int i = 0; i < n/2; i++)
{
current += next;
next += current;
}
return n % 2 == 0 ? current : next;
}
public static List<Long> fibList(int n)
{
List<Long> ret = new ArrayList<>(n == 0 ? List.of(0L) : List.of(0L, 1L));
long current = 0;
long next = 1;
for(int i = 0; i < n/2; i++)
{
current += next;
next += current;
if(i*2+1 <= n)
ret.add(current);
if(i*2+2 < n)
ret.add(next);
}
return ret;
}
}
Output:
0
1
1
2
3
5
8
13
21
34
55
89
144
[0]
[0, 1]
[0, 1, 1]
[0, 1, 1, 2]
[0, 1, 1, 2, 3]
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 13]
[0, 1, 1, 2, 3, 5, 8, 13, 21]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]

One problem with your code is that Fibonacci.fib doesn't return anything, so what are you expecting the FibonacciRunner to print?
Another is that arrays in Java have fixed length. Consider using a List instead:
List fibby = new ArrayList();
fibby.add(0);
fibby.add(1);
for (int i = 2; i < n; i++){
fibby.add(fibby.get(i - 1) + fibby.get(i - 2));
}

Related

How can I shift the elements of an Array to the order I desire? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm working on a problem that says "Given an array of N items, take the item from the first position and arrange the array such that the item in its final ordered position and all of the items <= to that item come before it and all of the items >= come after it. The list is not sorted. Only one item is in its final order." What I am trying to do is sort an array so the I get the elements that are smaller than or equal to the element at array[0] to be in the array first then a[0], and at the end of the array should the elements that are greater than or equal to array[0]. For Example, if I have an array of 10 numbers like this "[3, 2, 8, 1, 9, 5, 1, 9, 5, 9]" My new array should be "[2, 1, 1, 3, 8, 9, 5, 9, 5, 9]". I've tried writing the code below but it doesn't work as it should. The output I get is instead [3, 5, 1, 2, 9, 9, 1, 9, 8, 5]. Can someone help me figure out how to fix this?
import java.util.Arrays;
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
int[] d = createRandomIntArray(10);
System.out.println("Original Array: " + Arrays.toString(d));
changeOrder(d);
System.out.println("New Array: " + Arrays.toString(d));
}
public static int[] createRandomIntArray(int n) {
Random random = new Random();
int[] result = new int[n];
for (int i = 0; i < n; i++)
result[i] = random.nextInt(n);
return result;
}
public static void swap(int[] x, int i, int j) {
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
public static void changeOrder(int[] array) {
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
if (array[0] <= array[i + 1]) {
swap(array, array[0], array[count++]);
} else if (array[0] >= array[i + 1]) {
swap(array, array[i + 1], array[array.length - 1]);
}
}
}
}
It seems that the algorithm should be reconsidered just to move the lower elements before the head element starting at position 0:
if current element is less than head, rotate all elements from head to current position to the right by 1.
Example implementation:
static void arrange(int[] arr) {
int head = 0;
for (int i = head + 1; i < arr.length; i++) {
if (arr[i] < arr[head]) {
rotate(arr, head, i);
head++;
}
}
}
static void rotate(int[] arr, int head, int i) {
int tmp = arr[i];
for (int j = i; j > head; j--) {
arr[j] = arr[j - 1];
}
arr[head] = tmp;
}
Test:
int[] arr = {3, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [3, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 1, 1, 3, 8, 9, 5, 9, 5, 9]
int[] arr = {9, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [9, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 8, 1, 5, 1, 5, 9, 9, 9, 9]

Longest Plateau Solution: the length and location of the longest continuous sequence of equal values

Here is a full program description with test cases and below it is my solution:
Given an array of integers int A[], find the length and location of the longest contiguous sequence of equal values for which the values of the elements just before and just after this sequence are smaller.
You should just print these two numbers (first is the length and second is the starting index of the plateau).
To complete the definition, we can consider there are imaginary index positions at A[-1] and A[A.length] where A[-1] < A[0] and A[A.length] < A[A.length-1]. Therefore, the plateau can start/end at both ends of array A. This condition guarantees the existence of a plateau. A plateau can be of length 1.
Example 1:
java LongestPlateau 1 2 2 2 2 1
With these command-line arguments, the program should print:
4
1
Example 2:
java LongestPlateau 1 2 2 2 2 3
With these command-line arguments, the program should print:
1
5
Example 3:
java LongestPlateau 3 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1 0
With these command-line arguments, the program should print:
4
12
Here is my Solution:
public class LongestPlateau {
private static int[] parseInputArray(String[] args) {
int[] value = new int[args.length+1];
for(int i = 0 ; i < args.length; i++){
if (i == args.length-1) value[i] = 0; // this imaginary last value of the array ensures that if the plateau is the last value of the array, then it outputs the correct answer
value[i] = Integer.parseInt(args[i]);
}
return value;
}
public static void printLargestPlateau(int[] values) {
int biggestStartIndex = -1;
int biggestLength = 0;
int currentIndex = 1;
int currentPlateauStartIndex = 1;
int currentLength = 1;
boolean plateauStarted = false;
while (currentIndex < values.length) {
if(isStartOfPlateau(currentIndex, values)){
currentLength = 1;
plateauStarted = true;
currentPlateauStartIndex = currentIndex;
} else if (isEndOfPlateau(currentIndex, values)) {
if(plateauStarted && currentLength > biggestLength){
biggestLength = currentLength;
biggestStartIndex = currentPlateauStartIndex;
}
plateauStarted = false;
currentLength = 1;
} else {
currentLength++;
}
currentIndex++;
}
System.out.println(biggestLength +"\n"+biggestStartIndex);
}
private static boolean isStartOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index-1] < values[index];
}
private static boolean isEndOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index - 1] > values[index];
}
public static void main(String[] args) {
int[] values = parseInputArray(args);
printLargestPlateau(values);
}
}
As I mentioned in the comments, existing code fails to detect plateaus at the start and the end of the input data, and the following implementation fixes this issue.
static void printLargestPlateau(int ... arr) {
int start = -1, maxStart = -1;
int length = 0, maxLength = -1;
boolean onPlateau = false;
if (arr.length > 0) {
start = 0;
length = 1;
onPlateau = true;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == arr[i - 1]) {
if (onPlateau) {
length++;
}
} else if (arr[i] < arr[i - 1]) {
if (length > maxLength) {
maxLength = length;
maxStart = start;
}
onPlateau = false;
} else { // possible start of new plateau
onPlateau = true;
start = i;
length = 1;
}
}
// check possible plateau at the end
if (length > maxLength) {
maxLength = length;
maxStart = start;
}
}
System.out.println(maxLength);
System.out.println(maxStart);
}
Tests:
int[][] tests = {
{},
{1},
{1, 1},
{1, 2},
{1, 1, 2},
{1, 2, 2},
{1, 2, 1},
{1, 2, 3},
{1, 2, 2, 2, 3, 3, 1, 1, 1, 1},
{1, 2, 2, 2, 2, 1},
{1, 2, 2, 2, 2, 3},
{3, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 1, 0},
{3, 3, 3, 3, 1, 1, 0, 2, 2, 2, 2, 2, 2}
};
for (int[] arr : tests) {
System.out.println(Arrays.toString(arr));
printLargestPlateau(arr);
System.out.println("-".repeat(arr.length * 3));
}
Output:
[]
-1
-1
[1]
1
0
---
[1, 1]
2
0
------
[1, 2]
1
1
------
[1, 1, 2]
1
2
---------
[1, 2, 2]
2
1
---------
[1, 2, 1]
1
1
---------
[1, 2, 3]
1
2
---------
[1, 2, 2, 2, 3, 3, 1, 1, 1, 1]
2
4
------------------------------
[1, 2, 2, 2, 2, 1]
4
1
------------------
[1, 2, 2, 2, 2, 3]
1
5
------------------
[3, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 1, 0]
4
12
---------------------------------------------------
[3, 3, 3, 3, 1, 1, 0, 2, 2, 2, 2, 2, 2]
6
7
---------------------------------------

loop an array to group values for a total

How can I write a for loop that goes through an array and splits it into groups of 6. From there it should add the first group in the arrNumbers, then add the second group but reversed so { 6, 5, 4, 3, 2, 1 } to first group which is { 1, 2, 3, 4, 5, 6 } and then third group should be not reversed, but then if there is another group of 6, the set should be reversed to add. I don't know how to go about this. Any help will be appreciated. Below is my attempt
import java.util.Arrays;
public class arrayAdding{
public static void main(String []args){
int[] arrNumbers = new int[] { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 };
int[] newArrNumbers = new int[6];
for(int i = 0; i < arrNumbers.length ; i++){
newArrNumbers[i < 6 ? i : (6 - (i % 6) - 1)] += arrNumbers[i];
}
System.out.println(Arrays.toString(newArrNumbers));
}
}
Actual Result from my code:
newArrNumbers = [13, 12, 11, 10, 9, 8]
The required result should be:
newArrNumbers = [8, 9, 10, 11, 12, 13]
You can think like group of 12 elements and not reversed for the first 6 and reversed for the next 6.
(i % 12) < 6 - First half - i % 6
(i % 12) >= 6 - Second half(reversed) - (6 - (i % 6) - 1)
Code:
newArrNumbers[(i % 12) < 6 ? i % 6 : (6 - (i % 6) - 1)] += arrNumbers[i];
You can refer below code:
import java.util.*;
public class ArrayAdding {
public static void main(String []args){
Integer[] arrNumbers = new Integer[] { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 };
int[] newArrNumbers = new int[6];
List<List<Integer>> partitions = ArrayAdding.splitArray(arrNumbers);
Iterator<List<Integer>> itr = partitions.iterator();
while (itr.hasNext()) {
List<Integer> next = itr.next();
if (next.size() < 6 )
itr.remove();
}
for(int i = 0; i < partitions.size() ; i++){
if (i % 2 != 0) {
Collections.reverse(partitions.get(i));
}
}
for (List<Integer> partition : partitions) {
for (int j = 0; j < 6; j++) {
newArrNumbers[j] = partition.get(j) + newArrNumbers[j];
}
}
System.out.println(Arrays.toString(newArrNumbers));
}
private static List<List<Integer>> splitArray(Integer[] arrNumbers) {
int partitionSize = 6;
List<List<Integer>> partitions = new LinkedList<>();
List<Integer> originalList = Arrays.asList(arrNumbers);
for (int i = 0; i < originalList.size(); i += partitionSize) {
partitions.add(originalList.subList(i,
Math.min(i + partitionSize, originalList.size())));
}
return partitions;
}}

How to remove duplicate numbers that occurred more than twice, but keep the first two occurances

So I came across this problem in Java that wants to remove a list of number that has occurred more than twice but keeping the order, and the first two occurrences.
For example, if the list is 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10
the expected output would be 2, 3, 5, 4, 5, 2, 4, 3, 10
I've tried several methods, including using a counter int to keep track of the occurrences and filter it out, but I am not sure how I can go about it
class DeDup {
// function to find the element occurring more than 3 times
static void get2Occurrences(int arr[]) {
int i;
int count = 0;
for (i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i] == arr[j])
count++;
}
if (count < 3 && count > 0) {
//return arr[i];
System.out.print(arr[i] + ", ");
} else {
for (int k = 2; k > 0; k--) {
System.out.print(arr[i] + ", ");
}
}
}
}
// driver code
public static void main(String[]args) {
int arr[] = new int[]{ 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10 };
//expected output: 2, 3, 5, 4, 5, 2, 4, 3, 10
//int n = arr.length;
get2Occurrences(arr);
}
}
the expected output would be 2, 3, 5, 4, 5, 2, 4, 3, 10
but i got 2, 2, 3, 3, 5, 5, 4, 4, 5, 5, 2, 2, 4, 4, 3, 3, 5, 5, 2, 2, 4, 4, 4, 4, 2, 2, 10, 10,
I would do it using a pair of Sets: Set.add returns a boolean indicating whether the element was added. Hence:
boolean b = set1.add(num) || set2.add(num);
will be true if it was added into either set - and it will only try to add it to set2 if it was already in set1 - and false otherwise, meaning it was present in both sets already.
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for (Integer a : arr) {
if (set1.add(a) || set2.add(a)) {
System.out.print(a + ", ");
}
}
Ideone demo
Keep track of the number of occurrences found for each element.
Something like this:
static void get2Occurrences(int arr[])
{
// Initialize occurrences found
Hashtable<Integer, Integer> found_elms = new Hashtable<Integer, Integer>();
// Loop over all elements
int counter;
int number;
Integer found;
for (counter = 0; counter < arr.length; counter++)
{
number = arr[counter];
found = found_elms.get(number);
if (found == null)
found = 1;
else
found = found + 1;
found_elms.put(number, found);
if (found < 3)
System.out.print(number + ", ");
}
System.out.println();
} // get2Occurrences
In this solution, you can change the number of repetitions from three to another.
int[] arr = new int[]{2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10};
Map<Integer, Integer> counting = new HashMap<>();
for (Integer current : arr) {
int count = counting.compute(current, (x, n) -> n == null ? 1 : n + 1);
if (count < 3) {
System.out.print(current + ", ");
}
}
I would propose an insert filter : go through each element with a for loop and insert it into a response array if the response arrays doesnt contain it 2 times yet
import java.util.ArrayList;
import java.util.List;
...
List<Integer> lst = new ArrayList<>();
for (int i : arr) {
if (lst.lastIndexOf(i) == lst.indexOf(i)) {
lst.add(i);
}
}
return lst.stream().mapToInt(i -> i).toArray();
So this is what I came up with in the end
import java.util.ArrayList;
import java.util.Arrays;
class DeDup {
// function to find the element occurring more than 3 times
static void get2Occurrences(ArrayList<Integer> arr)
{
for(int i=0; i<arr.size(); i++){
int count=0;
for(int j=0; j<i; j++){
if(arr.get(j)==arr.get(i)){
count++;
}
}
if (count>=2){
arr.remove(i);
i--;
}
}
System.out.println("Output: "+arr);;
}
// driver code
public static void main(String[] args)
{
ArrayList<Integer> arr = new ArrayList<Integer>(Arrays.asList( 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10));
//expected output: 2, 3, 5, 4, 5, 2, 4, 3, 10
//int n = arr.length;
System.out.println("Input: "+arr);
get2Occurrences(arr);
}
}
Solution using Iteartor:
List<Integer> array = Lists.newArrayList(2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10);
Map<Integer, Integer> control = new HashMap<>();
Iterator<Integer> iterator = array.iterator();
while(iterator.hasNext()) {
Integer element = iterator.next();
Integer occurrences = control.getOrDefault(element, 0);
if (occurrences >= 2) {
iterator.remove();
} else {
control.put(element, occurrences + 1);
}
}

Rotate array by arbitrary step size without creating second array

So for a step size of 1, I want the array:
{1, 2, 3, 4}
To become:
{4, 1, 2, 3}
And for a step of size 2 the result will be:
{3, 4, 1, 2}
This is the code I'm using now:
private static int[] shiftArray(int[] array, int stepSize) {
if (stepSize == 0)
return array;
int shiftStep = (stepSize > array.length ? stepSize % array.length : stepSize);
int[] array2 = new int[array.length];
boolean safe = false;
for (int i = 0; i < array.length; i++) {
if (safe) {
array2[i] = array[i - shiftStep];
}
else {
array2[i] = array[array.length - shiftStep + i];
safe = (i+1) - shiftStep >= 0;
}
}
return array2;
}
The code is working great, but is it possible to achieve this without creating a helper array (which is array2 in the code above)?
Thanks!
You can do it without creating as big an array:
// void return type as it shifts in-place
private static void shiftArray(int[] array, int stepSize) {
// TODO: Cope with negative step sizes etc
int[] tmp = new int[stepSize];
System.arraycopy(array, array.length - stepSize, tmp, 0, stepSize);
System.arraycopy(array, 0, array, stepSize, array.Length - stepSize);
System.arraycopy(tmp, 0, array, 0, stepSize);
}
So for a 100,000 array and a step size of 10, it creates a 10-element array, copies the last 10 elements into it, copies the first 999,990 elements to be later, then copies from the temporary array back to the start of the array.
Use not the i++, but i += shiftSize and several loops (amount of them would be equal to gcd of array.length and shifSize).
Then you'll need only one int as buffer and execution time will be almost the same.
You could do it with a couple of loops, but its not easy. Using recursion is simpler in this case.
public static void main(String... args) {
for (int i = 0; i < 12; i++) {
int[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
rotateLeft(ints, i);
System.out.println(Arrays.toString(ints));
}
}
public static void rotateLeft(int[] array, int num) {
rotateLeft(array, num, 0);
}
private static void rotateLeft(int[] array, int num, int index) {
if (index >= array.length) return;
int tmp = array[(index + num) % array.length];
rotateLeft(array, num, index + 1);
array[index] = tmp;
}
prints
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
[5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4]
[6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]
[7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
[8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7]
[9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8]
[10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Yes it's possible, you'd only need to temporary store one element additional to the array.
Basically what you want to do is to:
store last element in tmp var
shift all elements to the right by one starting with the second to last element
sotre tmp var as first element
repeat from step 1 depending on your stepsize
This is not tested ...
public void rotateByStep(int[] array, int step) {
step = step % array.length;
if (step == 0) {
return;
}
int pos = step;
int tmp = array[0];
boolean inc = array.length % step == 0;
for (int i = 0; i < array.length; i++) {
int tmp2 = array[pos];
array[pos] = tmp;
tmp = tmp2;
pos = (pos + step) % array.length;
if (inc && pos < step) {
array[pos] = tmp;
pos++;
tmp = array[pos];
}
}
}
The idea I'm trying to implement is as follows:
If step isn't a factor of length, then incrementing an index (pos) by step modulo length starting from zero will visit every array element once after length iterations.
If step is a factor of length, then index (incremented as above) will get back to its starting point after length / step iterations. But if you then increment by one, you can process the cycle starting at 1, and then at 2, and so on. After length iterations, we'll have visited every array element once.
The rest is just rippling the element values as we cycle through the element indexes ... with some adjustment when we increment to the next cycle.
The other complete solutions have the advantage that they are much easier to understand, but this one requires no extra heap storage (i.e. no temporary array), and does the job in array.length loop iterations.
In n- 1 iterations
#include <stdio.h>
int main(int argc, char **argv) {
int k = 0, x = 0;
int a[] = {-5,-4,-1,0,1,2,30,43,52,68,700,800,9999};
int N = 0, R = 57; /*R = No of rotations*/
int temp = 0, temp2 = 0, start = 0, iter = 0;
x = 0;
temp2 = a[x];
N = sizeof(a) / sizeof(a[0]);
for ( k = 0; k < N - 1; k++) {
x = x + R;
while ( x >= N ) {
x = x - N;
}
temp = a[x];
a[x] = temp2;
temp2 = temp;
if ( x == start ) {
start = start + 1;
x = x + 1;
temp2 = a[x];
}
iter++;
}
a[start] = temp2;
for ( k = 0; k < N; k++) {
printf(" %d", a[k]);
}
printf("\n");
printf("Done in %d iteration\n", iter);
return 0;
}

Categories