java array rotating by n element gives wrong output in test - java

I have a problem with an exercise trying to solve it. Here is the task:
Write a program that moves that rotates a list several times (the first element becomes last).
list = 1,2,3,4,5 and N = 2 -> result = 3,4,5,1,2
Note that N could be larger than the length of the list, in which case you will rotate the list several times.
list = 1,2,3,4,5 and N = 6 -> result = 2,3,4,5,1
Input
On the first line you will receive the list of numbers.
On the second line you will receive N
Output
On the only line of output, print the numbers separated by a space.
Here are the TEST:
TEST 1:
Input 5,3,2,1 2
Output 2,1,5,3
TEST 2:
Input 2,1,3,4 5
Output 1,3,4,2
Here is my code so far:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] elements = input.split(",");
int[] array = new int[elements.length];
for (int i = 0; i < elements.length; i++) {
array[i] = Integer.parseInt(elements[i]);
}
int a = scanner.nextInt();
int[] rotated = new int[elements.length];
for (int x = 0; x <= array.length - 1; x++) {
rotated[(x + a) % array.length] = array[x];
}
for (int i = 0; i < rotated.length; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(rotated[i]);
}
}
}
The first TEST is passed. But the second test is not passed and my program gives me wrong output: 4,2,1,3 instead of the right one: 1,3,4,2.
I cant figure it out where is the problem.
Thank you in advance for any help.

Your logic can be simplified to :
public static void shiftLeft(int shiftBy, int arr[]) {
for (int j = 0; j < shiftBy; j++) {
int a = arr[0]; // storing the first index
int i;
for (i = 0; i < arr.length - 1; i++) { // shifting the array left
arr[i] = arr[i + 1];
}
arr[i] = a; // placing first index at the end
}
}
Now call it :
public static void main(String[] args) {
// Fetch all data from user as you have done
int arr[] = { 1, 2, 3, 4, 5 };
shiftLeft(n % arr.length, arr);
// print out the array
}
Notice that if the number n is greater than the length of the array, you don't have to actually shift it that many times. Instead you just need to shift it n % arr.length times.

Related

How to shift element an int left in an array then adding a number to the end? [duplicate]

I have an array of objects in Java, and I am trying to pull one element to the top and shift the rest down by one.
Assume I have an array of size 10, and I am trying to pull the fifth element. The fifth element goes into position 0 and all elements from 0 to 5 will be shifted down by one.
This algorithm does not properly shift the elements:
Object temp = pool[position];
for (int i = 0; i < position; i++) {
array[i+1] = array[i];
}
array[0] = temp;
How do I do it correctly?
Logically it does not work and you should reverse your loop:
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
Alternatively you can use
System.arraycopy(array, 0, array, 1, position);
Assuming your array is {10,20,30,40,50,60,70,80,90,100}
What your loop does is:
Iteration 1: array[1] = array[0]; {10,10,30,40,50,60,70,80,90,100}
Iteration 2: array[2] = array[1]; {10,10,10,40,50,60,70,80,90,100}
What you should be doing is
Object temp = pool[position];
for (int i = (position - 1); i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
You can just use Collections.rotate(List<?> list, int distance)
Use Arrays.asList(array) to convert to List
more info at: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#rotate(java.util.List,%20int)
Instead of shifting by one position you can make this function more general using module like this.
int[] original = { 1, 2, 3, 4, 5, 6 };
int[] reordered = new int[original.length];
int shift = 1;
for(int i=0; i<original.length;i++)
reordered[i] = original[(shift+i)%original.length];
Just for completeness: Stream solution since Java 8.
final String[] shiftedArray = Arrays.stream(array)
.skip(1)
.toArray(String[]::new);
I think I sticked with the System.arraycopy() in your situtation. But the best long-term solution might be to convert everything to Immutable Collections (Guava, Vavr), as long as those collections are short-lived.
Manipulating arrays in this way is error prone, as you've discovered. A better option may be to use a LinkedList in your situation. With a linked list, and all Java collections, array management is handled internally so you don't have to worry about moving elements around. With a LinkedList you just call remove and then addLast and the you're done.
Try this:
Object temp = pool[position];
for (int i = position-1; i >= 0; i--) {
array[i+1] = array[i];
}
array[0] = temp;
Look here to see it working: http://www.ideone.com/5JfAg
Using array Copy
Generic solution for k times shift k=1 or k=3 etc
public void rotate(int[] nums, int k) {
// Step 1
// k > array length then we dont need to shift k times because when we shift
// array length times then the array will go back to intial position.
// so we can just do only k%array length times.
// change k = k% array.length;
if (k > nums.length) {
k = k % nums.length;
}
// Step 2;
// initialize temporary array with same length of input array.
// copy items from input array starting from array length -k as source till
// array end and place in new array starting from index 0;
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
// step3:
// loop and copy all the remaining elements till array length -k index and copy
// in result array starting from position k
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
// step 4 copy temp array to input array since our goal is to change input
// array.
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
code
public void rotate(int[] nums, int k) {
if (k > nums.length) {
k = k % nums.length;
}
int[] tempArray = new int[nums.length];
System.arraycopy(nums, nums.length - k, tempArray, 0, k);
for (int i = 0; i < nums.length - k; i++) {
tempArray[k + i] = nums[i];
}
System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
}
In the first iteration of your loop, you overwrite the value in array[1]. You should go through the indicies in the reverse order.
static void pushZerosToEnd(int arr[])
{ int n = arr.length;
int count = 0; // Count of non-zero elements
// Traverse the array. If element encountered is non-zero, then
// replace the element at index 'count' with this element
for (int i = 0; i < n; i++){
if (arr[i] != 0)`enter code here`
// arr[count++] = arr[i]; // here count is incremented
swapNumbers(arr,count++,i);
}
for (int j = 0; j < n; j++){
System.out.print(arr[j]+",");
}
}
public static void swapNumbers(int [] arr, int pos1, int pos2){
int temp = arr[pos2];
arr[pos2] = arr[pos1];
arr[pos1] = temp;
}
Another variation if you have the array data as a Java-List
listOfStuff.add(
0,
listOfStuff.remove(listOfStuff.size() - 1) );
Just sharing another option I ran across for this, but I think the answer from #Murat Mustafin is the way to go with a list
public class Test1 {
public static void main(String[] args) {
int[] x = { 1, 2, 3, 4, 5, 6 };
Test1 test = new Test1();
x = test.shiftArray(x, 2);
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
}
public int[] pushFirstElementToLast(int[] x, int position) {
int temp = x[0];
for (int i = 0; i < x.length - 1; i++) {
x[i] = x[i + 1];
}
x[x.length - 1] = temp;
return x;
}
public int[] shiftArray(int[] x, int position) {
for (int i = position - 1; i >= 0; i--) {
x = pushFirstElementToLast(x, position);
}
return x;
}
}
A left rotation operation on an array of size n shifts each of the array's elements unit to the left, check this out!!!!!!
public class Solution {
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
String[] nd = scanner.nextLine().split(" ");
int n = Integer.parseInt(nd[0]); //no. of elements in the array
int d = Integer.parseInt(nd[1]); //number of left rotations
int[] a = new int[n];
for(int i=0;i<n;i++){
a[i]=scanner.nextInt();
}
Solution s= new Solution();
//number of left rotations
for(int j=0;j<d;j++){
s.rotate(a,n);
}
//print the shifted array
for(int i:a){System.out.print(i+" ");}
}
//shift each elements to the left by one
public static void rotate(int a[],int n){
int temp=a[0];
for(int i=0;i<n;i++){
if(i<n-1){a[i]=a[i+1];}
else{a[i]=temp;}
}}
}
You can use the Below codes for shifting not rotating:
int []arr = {1,2,3,4,5,6,7,8,9,10,11,12};
int n = arr.length;
int d = 3;
Programm for shifting array of size n by d elements towards left:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {4,5,6,7,8,9,10,11,12,10,11,12}
public void shiftLeft(int []arr,int d,int n) {
for(int i=0;i<n-d;i++) {
arr[i] = arr[i+d];
}
}
Programm for shifting array of size n by d elements towards right:
Input : {1,2,3,4,5,6,7,8,9,10,11,12}
Output: {1,2,3,1,2,3,4,5,6,7,8,9}
public void shiftRight(int []arr,int d,int n) {
for(int i=n-1;i>=d;i--) {
arr[i] = arr[i-d];
}
}
import java.util.Scanner;
public class Shift {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
int array[] = new int [5];
int array1[] = new int [5];
int i, temp;
for (i=0; i<5; i++) {
System.out.printf("Enter array[%d]: \n", i);
array[i] = input.nextInt(); //Taking input in the array
}
System.out.println("\nEntered datas are: \n");
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array[i]); //This will show the data you entered (Not the shifting one)
}
temp = array[4]; //We declared the variable "temp" and put the last number of the array there...
System.out.println("\nAfter Shifting: \n");
for(i=3; i>=0; i--) {
array1[i+1] = array[i]; //New array is "array1" & Old array is "array". When array[4] then the value of array[3] will be assigned in it and this goes on..
array1[0] = temp; //Finally the value of last array which was assigned in temp goes to the first of the new array
}
for (i=0; i<5; i++) {
System.out.printf("array[%d] = %d\n", i, array1[i]);
}
input.close();
}
}
Write a Java program to create an array of 20 integers, and then implement the process of shifting the array to right for two elements.
public class NewClass3 {
public static void main (String args[]){
int a [] = {1,2,};
int temp ;
for(int i = 0; i<a.length -1; i++){
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
for(int p : a)
System.out.print(p);
}
}

Java 2D arrays coin collection game from larger neigbouring cell

My issue is the following:
I have a 2D array of size n x m, entered on a single line. On the next n lines there are m number of elements, that fill the array. So far so good.
There is a pawn on the field that always starts at the only 0 on the field (assuming there is always one 0).
It can move up and down, right and left. It always moves to the neighbouring cell with most coins and at each move collects 1 coin (=> empties the visited cell by 1). The pawn does this until there are only 0s around it and it can collect nothing anymore. I need to find the sum of all coins collected.
Here is a representation of first steps in Paint:
Coin Collection first steps:
Sample input:
4 3, 3 2 4, 2 0 3, 1 1 5, 2 2 5 -> output: 22
Here is my code so far:
I have some unfinished work with the targetCell (I still wonder how to get its coordinates dynamically in a loop, so that each cell with a larger value than the previous turns to a targetCell.) Also I'm stuck with using the directions I just created. Any hints would be useful for me to further develop the task.
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] my_array = input.split(" ");
int[] array = Arrays.stream(my_array).mapToInt(Integer::parseInt).toArray();
int n = array[0]; // rows of matrix
int m = array[1]; // cols of matrix
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
String line = scanner.nextLine();
String[] numbers = line.split(" ");
matrix[i] = new int[m];
for (int j = 0; j < m; j++) {
matrix[i][j] = Integer.parseInt(numbers[j]);
}
}
int startPoint = 0;
int currentRow = 0;
int currentCol = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
startPoint = matrix[i][j];
currentRow = i;
currentCol = j;
}
}
}
int target1 = 0;
int target2 = 0;
int targetCell = 0;
target1 = Math.max(matrix[currentRow - 1][currentCol], matrix[currentRow + 1][currentCol]);
target2 = Math.max(matrix[currentRow][currentCol - 1], matrix[currentRow][currentCol + 1]);
targetCell = Math.max(target1, target2);
System.out.println(targetCell);
int hDirection = 1;
if (targetCol < currentCol) {
hDirection = -1;
}
int vDirection = 1;
if (targetRow < currentRow) {
vDirection = -1;
}
}
}
}
(Can't comment so will use an answer for now. Sorry)
My first thought would be to keep a global variable for the run so that when a coin is collected, it is added to its current value; similar to how you would keep score in games like Tetris. That's assuming I've read it right.
So something like:
private static int current_score = 0; //Assuming no use of objects so using static
Couldn't understand the sample input in this example. If you could give a three turn scenario of what the final score would be, I could give you better insight.

Java stdin not prompting program to run

I am working on a Merge-sort algorithm, and I am currently trying to test if it works.
It should be controlled through stdin with the input format:
array length
element values (separated by " ")
However, when typing in:
3
17 10 3
Nothing happens, and hitting enter, just get me to the next line in the console.
I get no error message (unless I type in wrong input), and so I have a hard time figuring out why the script is not prompted to run with the input given.
(Code is copied below)
package merge;
import java.io.*;
import java.util.*;
public class MergeSort
{
// This method takes two sorted arrays of integers as input parameters
// and it should return one sorted array of integers.
public int[] merge(int[] A1, int[] A2) {
int[] C = new int[A1.length + A2.length];
int i = 0, j = 0, k = 0;
while (i < A1.length && j < A2.length)
C[k++] = A1[i] < A2[j] ? A1[i++] : A2[j++];
while (i < A1.length)
C[k++] = A1[i++];
while (j < A2.length)
C[k++] = A2[j++];
return C;
}
// This method takes an array of integers as input parameter,
// and it should then return the integers sorted
// in ascending order using the MergeSort algorithm.
private int[] sort(int[] numbers) {
//pointers
int i = 0, j = 0, k = 0;
// reference values
int half = numbers.length / 2;
int[] sorted = new int[numbers.length];
if (numbers.length <= 1){
return numbers;
}
//left part of 'numbers'
int[] left = new int[half];
int[] right;
//right part of 'numbers'
if (numbers.length % 2 != 0){
right = new int[half+1];
j = half + 1;
}
else{
right = new int[half];
j = half;
}
//fills out left half of array with values from input array
while (i < half)
left[i] = numbers[i];
i++;
//fills out right half of array with values from input array
while (j < numbers.length)
right[j] = numbers[k];
j++; k++;
left = sort(left);
right = sort(right);
merge(left,right);
return sorted;
}
// ##################################################
// # Stdin part. #
// ##################################################
public static void main(String[] args) throws IOException {
new MergeSort().run();
}
private void run() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] numbers = readIntArray(in);
numbers = sort(numbers);
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
}
private int[] readIntArray(BufferedReader in) throws IOException {
int length = Integer.parseInt(in.readLine());
int[] array = new int[length];
StringTokenizer st = new StringTokenizer(in.readLine());
for (int i = 0; i < length; i++) {
array[i] = Integer.parseInt(st.nextToken());
}
return array;
}
}
You call readLine() two times, resulting in an attempt to read two lines on the standard input.

Program to find pairs in array that XOR to a given value

I am given an array and a value x.
Input example:
2 3
1 2
Where n (length of array) = 2, the value x = 3, and the next line (1, 2) contains the values in the array. I have to find the pairs of indices i, j so that a[i] XOR a[j] = x.
What I have implemented:
import java.util.HashSet;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x = sc.nextInt();
int[] arr = new int[n];
HashSet<Integer> hash = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
hash.add(arr[i]);
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.contains(arr[i]^x)) {
count++;
}
}
System.out.println(count/2);
}
}
I have the divided the result by two because we only want to count a given pair once (only count [1, 2] not [1, 2] and [2, 1]).
I pass the given test above where the output is 1, and this supplementary one where the output is 2.
6 1
5 1 2 3 4 1
However I seem to fail some extra ones which I cannot see.
The problem is that you check "contains", but for duplicate values this only returns a single occurrence. By using a set you throw duplicates away. Instead you should have a HashMap with number of occurrences:
Map<Integer, Integer> hash = new HashMap<>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
if (!hash.containsKey(arr[i])) {
hash.put(arr[i], 0)
}
hash.put(arr[i], hash.get(arr[i]) + 1);
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.containsKey(arr[i]^x)) {
count += hash.get(arr[i]^x);
}
}
Your logic of dividing the count by 2 as the final answer, is not correct.
Replace your logic by the following:
HashSet<Integer> hash = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int count = 0;
for (int i = 0; i < n; i++) {
if (hash.contains(arr[i]^x)) {
count++;
}
hash.add(arr[i]);
}
System.out.println(count);
Your program doesn't handle duplicate numbers properly. It deals with 5 1 2 3 4 1 okay because 1 isn't part of the solution. What if it is?
Let's say number a[i] ^ a[j] is a solution as is a[i] ^ a[k]. In other words, a[j] == a[k]. The line hash.contains(arr[i]^x) will only count a[i] once.
You can solve this by having nested for loops.
for (int i = ...) {
for (int j = ...) {
if (a[i] ^ a[j] == x) {
count++;
}
}
}
This approach lets you get rid of the hash set. And if you're clever enough filling out the ... parts you can avoid double counting the pairs and won't have to divide count by 2.

How do I get the right output for this array?

I'm trying to obtain specific outputs for an array. The array's been put in a while loop to continue to set up new arrays until it reaches its counter. The counter and the amount of elements in each array line up, but once I try to get my output, it doesn't work out. What should I fix to work it out?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int i; int j; int n; int u;
int count = 0;
n = input.nextInt();
System.out.println("Times repeated: " + n);
while(count < n) //counter represents amount of times loop will occur
{
i = input.nextInt();
int[] numbers = new int[i];
System.out.println("Length of Array: " + i);//represents how many numbers within a line
count++;
for(j = 0; j < numbers.length; j++) //numbers within line
{
numbers[j] = input.nextInt();}
for(int p = 0; p < numbers.length - 1; p++) //prints specific values in line
{
numbers[p] = numbers[numbers.length - 1 ];
p = numbers[p];
System.out.println(p);
System.out.println(Arrays.toString(numbers)); }
input.close();}
} }
First User Input:
3
2
10
1
Expected Output:
10
Instead, I get 1. What I wanted to do was subtract the last element of the array from the rest of the array to get the desired output. This includes the last element as well.
code works fine, just need to close scanner outside while. Fix the brackets.
input.close(); outside while loop
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int i;
int j;
int n;
int u;
int count = 0;
n = input.nextInt();
System.out.println("Times repeated: " + n);
while (count < n) // counter represents amount of times loop will occur
{
i = input.nextInt();
int[] numbers = new int[i];
System.out.println("Length of Array: " + i);// represents how many numbers within a line
count++;
for (j = 0 ; j < numbers.length ; j++) // numbers within line
{
numbers[j] = input.nextInt();
}
for (int p = 0 ; p < numbers.length - 1 ; p++) // prints specific values in line
{
numbers[p] = numbers[numbers.length - 1];
p = numbers[p];
System.out.println(p);
System.out.println(Arrays.toString(numbers));
}
}
input.close();
}
output
2
Times repeated: 2
2
Length of Array: 2
1
2
2
[2, 2]
2
Length of Array: 2
1
2
2
[2, 2]

Categories