Hi i'm trying to submit UVa 482 problem here:
In many computer problems, it is necessary to permute data arrays.
That is, the data in an array must be re-arranged in some specified
order. One way to permute arbitrary data arrays is to specify the
permutations with an index array to point out the position of the
elements in the new array. Let x be an array that is to be permuted
and let x' be the permuted array. Then, we have the relationship
between x and x' that x'pi = xi.
Input
The input begins with a single positive integer on a line by itself
indicating the number of the cases following, each of them as
described below. This line is followed by a blank line, and there is
also a blank line between two consecutive inputs. Each input set will
contain two lines of numbers. The first line will be an index array p
containing the integers 1...n, where n is the number of integers in
the list. The numbers in the first line will have been permuted in
some fashion. The second line will contain a list numbers in floating
point format.
Output
For each test case, the output must follow the description below. The
outputs of two consecutive cases will be separated by a blank line.
The output for this program will be the list of floating point numbers
from the input set, ordered according to the permutation array from
the input file. The output numbers must be printed one per line in the
same format in which they each appeared in the input file.
Sample Input
1
3 1 2
32.0 54.7 -2
Sample Output
54.7
-2
32.0
but verdict result is wrong answer, problem itself is not complicated but i'm really stuck!!!
here is my code:
import java.util.*;
class Main {
public static void main(String args[]) {
Main problem = new Main();
problem.solve();
}
void solve() {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int counter = 0;
while (counter != n) {
ArrayList<Integer> index = new ArrayList<>();
ArrayList<String> number = new ArrayList<>();
while (in.hasNextInt())
index.add(in.nextInt());
for (int i = 0; i < index.size(); i++)
number.add(in.next());
String sortedNumber[] = new String[index.size()];
for (int i = 0; i < index.size(); i++)
sortedNumber[index.get(i) - 1] = number.get(i);
for (int i = 0; i < index.size(); i++)
System.out.println(sortedNumber[i]);
if (counter < n - 1)
System.out.println();
counter++;
}
in.close();
}
}
i tested for some limited inputs also, but i could not figure it out.
You are assuming that no floating-point number is also an integer. If it is, your program does weird things.
Try this input:
2
1 2 3
0 2.0 3.0
1 2 3
1.1 2.2 3.3
You should have read permutations line-by-line:
String line = in.nextLine();
for (String s : line.split(" ")) {
index.add(Integer.parseInt(s));
}
instead of
// fails when there's starting ints in the "floating-point" line
while (in.hasNextInt()) index.add(in.nextInt());
Related
I am doing the Hackerrank questions to get better at solving puzzles. I've been working on the Simple Sum Array question in the Data Structures section for nearly 2 hours O_O
I seriously thought I solved it because I tested it on the terminal on my mac and it ran fine, but when I submit the code in Hackerrank, it failed all 3 test cases T_T
I don't understand where the problem is and why the test cases failed. Does anyone see the problem? Please help.
Below is the code:
import java.io.*;
import java.util.*;
public class Solution {
public static int sumArray( int[] arr ){ //arr stands for the array to pass in
int result = 0;
for (int i = 0; i < arr.length; i++){
result = result + arr[i];
}
return result;
}
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner input = new Scanner(System.in);
System.out.println("Print out the size of the array: ");
int size = input.nextInt();
int[] array = new int[size];
System.out.println("Type out the numbers you want in the array. One line only, each number is separated by a space");
String numbers = null;
String[] splitString = null;
while ( input.hasNextLine() ){
numbers = input.nextLine();
splitString = numbers.split("\\s");
if (splitString.length == size){
break;
}
}
//splitString = numbers.split("\\s");
int i = 0;
for (String s : splitString){
//System.out.println(s);
array[i] = Integer.parseInt(s);
i++;
}
System.out.println( sumArray(array) );
}
}
Also, here's the Hackerrank question to clarify what they wants:
Given an array of integers, can you find the sum of its elements?
Input Format:
The first line contains an integer, denoting the size of the array.
The second line contains space-separated integers representing the array's elements.
Output Format:
Print the sum of the array's elements as a single integer.
Sample Input:
6
1 2 3 4 10 11
Sample Output:
31
From the first time seeing your code you have two issues:
1- arr.length should be arr.length - 1
Because, your iteration starts from 0 and length not
2- the way you print your array is wrong
Because, you should use something like this:
Arrays.toString(array)
Prateek wants to give a party to his N friends on his birthday, where each friend is numbered from 1 to N. His friends are asking for a gift to come to the party, instead of giving him one. The cost of the gifts are given in the array Value where ith friend asks for a gift which has a cost Costi.
But, Prateek has only X amount of money to spend on gifts and he wants to invite his friends which are in continuous range such that sum of the cost of the gifts of those friends will be exactly equal to X.
If he can invite his friends, who can satisfy the above condition then, print YES otherwise print NO.
Input:
The first line contains a single integer T, denoting the number of test cases. In each test case, the following input will be present: - The next line contains two space-separated integers N and X, where N represents the number of friends and X represents amount of money which Prateek can spend on gifts.
- Next N line contains N integers, where ith line contains ith integer, which represents the Costi .
Ouput
Output exactly T lines, each containing the answer to the corresponding test case .
Constraints:
1 <= T <= 10
1 <= N , Costi <= 106
1 <= X <= 1012
Sample Input(Plaintext Link)
1
5 12
1
3
4
5
2
Sample Output(Plaintext Link)
YES
MyApproach
I followed what is said to take the input and took the subarry sum for every element.But I am not getting Expected output.
public static void counCondition()
{
boolean b1=false;
int Sum=0;
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
for(int i=1;i<=T;i++)
{
sc.nextLine();
String nextLine = sc.nextLine(); //#Edited my mistake
String[] input = nextLine.split("\\s+");
int p = Integer.parseInt(input[0]);
int c = Integer.parseInt(input[1]);
int Cost[]=new int[p];
for(int j=0;j<Cost.length;j++)
{
Cost[j]=sc.nextInt();
}
for(int k=0;k<Cost.length;k++)
{
Sum=0;
for(int l=k;l<p;l++)
{
Sum=Sum+Cost[l];
if(Sum>c)
{
break;
}
else if(Sum==c)
{
b1=true;
break;
}
}
}
if(b1==true)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
}
sc.close();
}
//#Edit Output is still the same.
**ActualInput** **ExpectedInput**
1 1
5 12 5 12
1 1
3 3
4 4
5 5
2 2
6
7
8
9
2
**ActualOutput** Expected Output(Plaintext Link)
NO YES
I am not expecting this output.
Can anyone guide me why?
Once you have got the individual cost in the Cost array.
Here is the logic to get continous sum equal to max sum.
Maintain a start index variable telling from where continous sequence is starting. In the start it should be zero index.
Maintain sum variable to track the total sum.
Run a for loop from zero to endIndex.
if sum less than max sum
Add Cost[i] to sum.
else if sum equals max sum, break the for loop
else if sum greater than max sum
Now remove elements from startIndex till sum again becomes less or equal to max sum using while loop.
while(sum > maxSum)
sum = sum - cost[startIndex]
increment startIndex
while loop finished
if sum equals maxsum, break the loop you got your answer
else continue the outer for loop.
The idea of this logic is to keep removing elements from start from the sum whenever sum increases the maxsum.
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
while(t>0)
{
int n=sc.nextInt();
long x=sc.nextLong();
long[] money=new long[n];
for(int i=0;i<n;i++)
{
money[i]=sc.nextInt();
}
long sum;
int c=0;
sum=money[0];
for(int i=1;i<n;i++)
{
if(sum<x)
sum=sum+money[i];
else if(sum==x)
break;
while(sum>x)
{
sum=sum-money[c];
c++;
}
}
if(sum==x)
System.out.println("YES");
else
System.out.println("NO");
t--;
}
here http://jayarampandava.blogspot.in/2015_10_01_archive.html
you can find the actual solution
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at app.HackerEarth25Dec2015.counCondition(HackerEarth25Dec2015.java:18)
The exception is occurring because you are calling next() method not the nextLine(). The next() method return the next token which 5 here not the complete line.
Also I would suggest you to use the nextInt() from the Scanner instead of getting the String and splitting and parsing it. That would be a cleaner way of doing things.
int p = sc.nextInt();
int c = sc.nextInt();
Also your logic is also not correct. I hope you will find the logical error and fix it.
You can use the below code for fixing the issue.
sc.nextLine(); // This is to read the `\n` left from previous `nextInt()`
String nextLine = sc.nextLine();
String[] input = nextLine.split("\\s+");
I am trying to add values into a 2d array from a text file. I cannot figure out how to convert the input file to teacher's array format. The file contains a first line that goes into an array that represents vertices. That part works fine. Every line after the first line contains numbers for the adjacency matrix. These numbers are read in but for some reason the slots in the matrix are not being filled. I need to use those numbers to fill a double array that would be the same as using this statement:
int[][] edges = {
{0,1}, {0,2},
{1,0},{1,2},
{2,0},{2,1},{2,3},{2,4},{2,6},
{3,2},{3,4},{3,5},
{4,2},{4,3},
{5,3},{5,6},
{6,2},{6,5},{6,7},
{7,6}
I have to read input from a txt file. The names represent the names of the nodes or vertices in my graph. The numbers represent the positions of the vertices in an adjacency matrix. For example the first line represents row o which maps to node john, and it means that john is connected by an edge to node 1 and 2 which are peter and mary. The numbers should map the same way as the array creation above. Here is what the file looks like :
john;peter;mary;susan;george;debbie;tom;bill;
0 1 2
1 0 2
2 0 1 3 4 6
3 2 4 5
4 2 3
5 3 6
6 2 5 7
7 6
And here is my code :
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestSocialGraph {
public static void main(String args[]){
String verts;
int[][] edges;
int[] intPasser;
File input = new File("GraphInput.txt");
String[] names;
try {
Scanner reader = new Scanner(input);
verts = reader.next();
names = verts.split(";");
edges = new int[names.length][names.length];
while (reader.hasNextLine()){
int b = 0;
int count = 0;
String passer = reader.nextLine();
// System.out.println(passer);
String[] temp = passer.split(" ");
intPasser = new int[temp.length];
for(int i = 1; i< temp.length; i++){
System.out.println(temp[i]);
intPasser[b] = Integer.parseInt(temp[i]);
b++;
}
System.out.println(intPasser[0]);
for(int i = 0; i< intPasser.length; i++){
edges[count][intPasser[i]] = 1;
}
count++;
}
} catch (FileNotFoundException e) {
System.out.println("File not found. Please place appropriate file and restart program");
System.exit(1);
}
}
}
It looks like you're trying to make an adjacency matrix...
I.e. The first line in your file says
0 1 2
So, this would mean node 0 is connected to node 1 & node 2. It matches with what your teacher has given also:
{0,1}, {0,2},
So, in the final 2D array edges, it should be represented like so (1s in the indexes to which node 0 is connected to):
edges[0] = {0, 1, 1, 0, 0, 0, 0, 0};
Dici's response is absolutely correct in this matter - it's the count variable's location that is creating a problem. Place int count = 0; outside the while loop, and use readLine() instead of read(), and you should get an adjacency matrix representation of that data.
The only problem is that the teacher's representation & the one you're trying to produce here are different. So, consequently, the later logic which processes these inputs will also vary. One program will run with what your teacher has provided, but won't run with the matrices you've created.
---------------------------EDIT---------------------------
In response to the comment, IMO, you'll need to go through the file twice - first to get the number of edges (in this case 20), then to fill your edges array with the actual values.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestSocialGraph {
public static void main(String args[]) {
int[][] edges;
File input = new File("GraphInput.txt");
try {
Scanner reader = new Scanner(input);
reader.nextLine();// Skips the first line (nameList)
int count = 0;
// Count the total number of 2 element arrays
while (reader.hasNextLine()) {
String passer = reader.nextLine();
count += passer.split(" ").length - 1;
}
reader.close();
edges = new int[count][];
int i = 0;
reader = new Scanner(input);
reader.nextLine();// Skips the first line (nameList)
while (reader.hasNextLine()) {
String passer = reader.nextLine();
String[] split = passer.split(" ");
for (int j = 1; j < split.length; j++) {
edges[i + j - 1] = new int[2];
edges[i + j - 1][0] = Integer.parseInt(split[0]);
edges[i + j - 1][1] = Integer.parseInt(split[j]);
}
i += split.length - 1;
}
reader.close();
print(edges);
} catch (FileNotFoundException e) {
System.out.println(e);
}
}
private static void print(int[][] e) {
for (int i = 0; i < e.length; i++) {
for (int j = 0; j < e[i].length; j++)
System.out.print(e[i][j] + " ");
System.out.println();
}
}
}
I hope the code isn't too obscure/unreadable.
There are a lot of things to correct in your code.
verts = reader.next(); should be verts = reader.nextLine();.
in your question edges is a 20 x 2 matrix whereas in your code it is a 8 x 8 square matrix. The number of edges in your file does not seem to depend of the number of names in the first line, so why instantiating the array of edges like this ?
variable b is useless, you can replace it with i in the loop
variable count is never incremented (or at least the incremented value is never used) since it is reinitialized at each turn of the loop. That is the reason why you never fill certain lines.
your two loops could be merged into a unic one, without using a temporary array
Where does you data come from? I would avoid writing/maintaining a parser yourself. This is a waste of time. Did you think about using JSON? Your data (in the Java-code version) looks exactly like that.
When you can turn your data into
{
"vertices" : ["john","peter","mary","susan","george","debbie","tom","bill"],
"edges" : [[0,1], [0,2], ...]
}
you can use a standard JSON parser to read into a document model and directly start using the data.
This is an example of how to work with JSON data:
http://www.mkyong.com/java/json-simple-example-read-and-write-json/
My assignment is to merge two arrays using int arrays that the user fills and we have to assume that there will be a maximum of 10000 inputs from the user, and the user inputs a negative number to stop. Then sort the array from least to greatest and print it out. Initially i thought that this would be quite easy but when i finished, i began getting outputs such as:
Enter the values for the first array, up to 10000 values, enter a negative number to quit: 1
3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
1
3
5
Second Array:
2
4
6
Merged Array:
6 1 2 3 4 5
as you can see, the six is out of place and i have no idea how to fix it. Here is the source code, i have included copious comments because I really want you guys to help me out to the best of your abilities. IF it's possible to use the same exact technique without implement new techniques and methods into the code please do so. I know there are methods in java that can do all of this in one line but it's for an assignment at a more basic level.
import java.util.Scanner;
public class Merge
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int [] first = new int[10000]; //first array, assume 10k inputs max
int [] second = new int[10000]; //first array, assume 10k inputs max
boolean legal = true; //WILL IMPLIMENT LATER
int end = 0; // set how many elements to put in my "both" array
int end2 = 0;// set how many elements to put in my "both" array
System.out.print("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
//get values
for(int i = 0; i<first.length; i++)
{
first[i] = scan.nextInt(); //fill first with user input
if(first[i] <0) //if negative number, stop loop
{
end = i; //get position of end of user input
break;
}
}
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
for(int i = 0; i<second.length; i++) //exact same as the first get values loop
{
second[i] = scan.nextInt();
if(second[i] <0)
{
end2 = i;
break;
}
}
System.out.print("First Array:\n");
for(int i = 0; i<first.length; i++) //print first array
{
if(i == end) //this prevents from printing thousands of zeros, only prints values that user inputed
break;
System.out.println(first[i] + " ");
}
System.out.print("Second Array:\n");
for(int i = 0; i<second.length; i++) //same as printing first array
{
if(i == end2)
break;
System.out.println(second[i] + " ");
}
int [] both = new int[(end)+(end2)]; //instanciate an int array to hold only inputted values from first[] and second[]
int [] bothF = new int[(end)+(end2)]; //this is for my simple sorter algotithm loop
for(int i = 0; i<both.length; i++) //fill both with the first array that was filled
{
both[i] = first[i];
}
int temp = end; // see below
for(int i = 0;i<both.length; i++) //fill array with the second array that was filled(starting from the end of the first array so that the first set is not overwritten
{
if(temp<both.length){ //this prevents an out of bounds
both[temp] = second[i];
temp++;}
}
//simple sorting algorithm
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
bothF[d] = both[d];
both[d] = both[i];
both[i] = bothF[d];
}
}
}
System.out.println("Merged Array:"); //print the results
for(int i = 0; i<both.length; i++)
{
System.out.print(both[i] + " ");
}
//System.out.println("ERROR: Array not in correct order");
}
Your sorting algorithm is faulty.
It's similar to selection sort, in that you take two elements and swap them if they're out of place. However, you don't stop the comparisons when you should: when the index d is less than the index i, the comparison-and-swap based on arr[d] > arr[i] is no longer valid.
The inner loop should terminate with i=d.
The logic of your sort goes something like this:
On the d-th loop, the elements at d+1 and to the right are correctly sorted (the larger numbers). This is true at the beginning, because there are 0 elements correctly sorted to the right of the right-most element.
On each of the outer loops (with the d counter), compare the d-th largest element slot with every unsorted element, and swap if the other element is larger.
This is sufficient to sort the array, but if you begin to compare the d-th largest element slot with already-sorted elements to its right, you'll end up with a larger number in the slot than should be. Therefore, the inner loop should terminate when it reaches d.
Sure, you can do it like this
for (int i = 0; i < end; i++) {
both[i] = first[i];
}
for (int i = 0; i < end2; i++) {
both[i + end] = second[i];
}
// simple sorting algorithm
for (int d = both.length - 1; d >= 0; d--) {
for (int i = 0; i < d; i++) {
if (both[i] > both[d]) {
int t = both[d];
both[d] = both[i];
both[i] = t;
}
}
}
Output(s) -
Enter the values for the first array, up to 10000 values, enter a negative number to quit3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
3
5
Second Array:
2
4
6
-1
Merged Array:
2 3 4 5 6
First I will start with some recommendations:
1.Give end1 and end2 the initial value as the array lengths.
The printing part - instead of breaking the loop - loop till i == end(if its not changed by the first part it will stay the array length).
One suggestion is to use a "while" statement on the user input to do the reading part (it seems cleaner then breaking the loop- but its OK to do it like you have done too).
Try to use more functions.
now to the main thing- why not to insert the numbers from both arrays to the join array keeping them sorted?
Guiding:
Keep a marker for each array.
Iterate over the new join array If arr1[marker1]> arr2[marker2]
insert arr2[marker2] to the joint array in the current position.
and add 1 to marker2. and the opposite.
(don't forget to choose what happens if the are equal).
This can be achieved because the arrays were sorted in the first place.
Have fun practicing!
I guess you have sort of a reverse "selection sort"-algorithm going on there. I made an class that run your code and printed out the output after every swap. Here is the code which is the same as you got in your application with the addition of print.
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
int temp = both[d];
both[d] = both[i];
both[i] = temp;
printArray(both);
}
}
}
and when we run this on an example array we get this output
[9, 8, 7, 6]=
-> 6879
-> 6789
-> 6798
-> 6978
-> 9678
The algorithm actually had the correct answer after two swaps but then it started shuffling them into wrong order. The issue is the inner for loops end parameter. When you have run the outer loop once, you can be certain that the biggest number is in the end. 'd' is here 3 and it will swap out a bigger number every time it encounters it. the if clause comparisions in the first loop is 6-9 (swap), 9-8, 9-7, 9-9. All good so far.
Potential problems comes in the second iteration with 'd' as 2. Array is now [6,8,7,9] and comparisons are 7-6, 7-8 (swap with result [6,7,8,9]), 8-8, 8-9 (swap!!) resulting in [6,7,9,8]. the last swap was the problematic one. We knew that the biggest number was already in the last spot, but we still compare against it. with every gotrough of the whole inner loop it will always find the biggest number (and all other bigger than both[d] that is already in place) and swap it to some wrong position.
As we know that the biggest number will be last after one iteration of the outer loop, we shouldn't compare against it in the second iteration. You sort of lock the 9 in the array and only try to sort the rest, being in this case [6,8,7] where d = 3, value 7. hence, your inner loop for(int i = 0; i<both.length; i++) becomes for(int i = 0; i<=d; i++). As an added bonus, you know that in the last iteration i==d, and thus the code inside it, if(both[d]<both[i]) will never be true, and you can further enhance the loop into for(int i = 0; i<d; i++).
In your algorithm you always do four comparisons in the inner loop over four iterations of the outer loop, which means there is a total of 16 comparisons. if we use the i<d we'll just do three comparisons in the inner loop on the first iteration of the outer loop, then two, then one. This brings it to a total of six comparisons.
Sorry if too rambling, just wanted to be thorough.
Okay here's a Java assignment I've been having trouble with. I asked earlier about this and got some good comments and advice, but have since understood the assignment more clearly and the issue has changed a bit. So here's the assignment:
***
Your task is to complete the program below by writing three methods (askInfo, copyInfo and setArray). Program should ask for integers (max 100 integers) until the users types in zero. Integers can vary from one to one hundred and they are stored in an array that has 100 elements. Numbers are asked for with the askInfo method, which receives the array with numbers as parameter. Method returns the number of integers. The number zero is not saved in the array; it is merely used to stop giving input. The given numbers are then copied to another array which size is the amount of given numbers. Copying is done with copyInfo method which receives both arrays as parameters. After this the elements of the new array are put in ascending order with setArray method and printed on screen with printArray method.
Program to complete:
import java.util.*;
public class RevisionExercise {
public static void main(String[] args) {
int[] tempArray = new int[100];
System.out.println("Type in numbers. Type zero to quit.");
int amountOfNumbers = askInfo(tempArray);
int[] realArray = new int[amountOfNumbers];
copyInfo(realArray, tempArray);
setArray(realArray);
printArray(realArray);
}
// Your code here
public static void printArray(int[] realArray ) {
System.out.println("\Ordered array: ");
for(int i = 0; i < realArray .length; i++) {
System.out.println(realArray [i]);
}
}
Example print:
Type in numbers. Type zero to quit.
1. number: 3
2. number: 8
3. number: 5
4. number: 6
5. number: 9
6. number: 0
Ordered array:
9
8
6
5
3
I'm struggling with the askInfo method. So far I've written this but it returns only zeroes. Here's my askInfo method:
public static int askInfo(int[] tempArray) { //askinfo-metodi
Scanner reader = new Scanner(System.in);
int i;
for (i = 0; i < tempArray.length; i++) {
System.out.print((i+1) + ". number: ");
tempArray[i] = reader.nextInt();
if (tempArray[i] == 0) {
return tempArray[i];
}
}
return tempArray[i];
}
***
How can I make it to register the input and get the amount of numbers to be passed to the next method in the assignment as described in the assignment.
You never store your integer luku values in your array, so your array never changes from the default initialized integer values of all zeroes. Inside your loop, you need to add an
tempA[i] = luku;
After the if-statement confirms that luku is not 0. All in all:
if (luku == 0) {
return i;
}
tempA[i] = luku;