Array Absurdity Challenge [closed] - java

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
So, I have been working on the following codeeval challenge problem.
Array Absurdity
Description:
Imagine we have an immutable array of size N which we know to be filled with integers ranging from 0 to N-2, inclusive. Suppose we know that the array contains exactly one duplicated entry and that duplicate appears exactly twice. Find the duplicated entry. (For bonus points, ensure your solution has constant space and time proportional to N)
Input sample:
Your program should accept as its first argument a path to a filename. Each line in this file is one test case. Ignore all empty lines. Each line begins with a positive integer(N) i.e. the size of the array, then a semicolon followed by a comma separated list of positive numbers ranging from 0 to N-2, inclusive. i.e eg.
5;0,1,2,3,0
20;0,1,10,3,2,4,5,7,6,8,11,9,15,12,13,4,16,18,17,14
Output sample:
Print out the duplicated entry, each one on a new line eg
0
4
Submit your solution in a file (some file name).(py| c| cpp| rb| pl| php| tcl| clj| js) | array_absurdity.java or use the online editor.
I find it rather easy. I coded it, tested it with various test cases on my computer and it seems to be working fine. But when I submit the problem on codeveal i keep getting a 0. I have thought of all possible test cases but idk why it keeps failing. I would appreciate if you guys could give some ideas. The following solution I coded is in java.
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
public class array_absurdity {
public static int findDuplicate(int [] arr){
int sumAll = 0;
int sumEle = sumElements(arr.length-2);
for(int i = 0; i < arr.length; i++){
sumAll += arr[i];
}
if(sumAll < sumEle)
return 0;
else
return (sumAll - sumEle);
}
public static int sumElements (int length){
/*
if(length == 0)
return 0;
else
return length + sumElements(length - 1);
*/
return length* (length + 1)/2;
}
static String[][] readNumbers (String fileName)
{
String [][] arr;
try {
LinkedList<String> stringList = new LinkedList<String>();
Scanner scanner = new Scanner (new FileReader (fileName));
while(scanner.hasNext()){
String input = scanner.next();
stringList.add(input);
}
Iterator<String> iter = stringList.iterator();
arr = new String [stringList.size()][];
int i = 0;
while(iter.hasNext()){
arr[i] = new String[2];
try{
arr[i] = iter.next().split(";");
}
catch (Exception e){
System.out.println (e);
System.exit (0);
}
i++;
}
// Done.
return arr;
}
catch (IOException e) {
System.out.println (e);
System.exit (0);
return null;
}
catch( ArrayIndexOutOfBoundsException e ) {
System.out.println (e);
System.exit (0);
return null;
}
}
public static void main (String[] argv){
int [] iArr;
String [] ele;
Scanner sc = new Scanner(System.in);
String filename = sc.nextLine();
String [][] arr = readNumbers (filename);
int size = 0;
for(int i = 0; i< arr.length; i++){
try{
ele = arr[i][1].split(",");
size = Integer.parseInt(arr[i][0]);
iArr = new int[ele.length];
if(size == iArr.length){
int duplicate = 0;
for (int j=0; j < ele.length; j++) {
iArr[j] = Integer.parseInt(ele[j]);
duplicate = findDuplicate(iArr);
}
System.out.println(duplicate);
}
}
catch( ArrayIndexOutOfBoundsException e ) {
System.out.println (e);
System.exit (0);
}
catch (Exception e) {
System.out.println (e);
System.exit (0);
}
}
System.exit(0);
}
}

A shorter version in Java.
public static void main(String... args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(args[0]));
for (String line; ((line = br.readLine()) != null); ) {
String[] parts = line.split(";")[1].split(",");
int num = (parts.length - 2) * (parts.length - 1) / 2;
for (String part : parts) num -= Integer.parseInt(part);
System.out.println(-num);
}
}

Your program should accept as its first argument a path to a filename.
Your program looks like it reads the filename from System.in instead of from the command line. It does nothing with the command-line arguments.
I haven't looked carefully at the rest of the code, but this seems to be something that might disqualify it even if the logic of the primary problem is correct.

Here's a basic way to do it in perl.
#!/usr/bin/perl -w
use strict;
open FILE, $ARGV[0] or die $!;
local $| = 1;
local $, = '';
while (<FILE>) {
$_ =~ /(\d+);(.*)/;
my $len = $1;
my #nums = sort split /,/, $2;
for(0 .. $len) {
print $nums[$_], "\n" and last if $nums[$_] == $nums[$_ + 1];
}
}

Related

how do i detect a double line break in a data file

I have a data file that consists of a calorie count.
the calorie count it separated by each elf that owns it and how many calories are in each fruit.
so this represents 3 elves
4323
4004
4070
1780
5899
1912
2796
5743
3008
1703
4870
5048
2485
1204
30180
33734
19662
all the numbers next to each other are the same elf. the separated ones are seperate.
i tried to detect the double line break like so
import java.util.*;
import java.io.*;
public class Main
{
public static void main(String [] args) throws FileNotFoundException
{
int[] elf = new int[100000];
int cnt = 0;
Scanner input = new Scanner(new File("Elf.dat"));
while(input.hasNext())
{
elf[cnt] += input.nextInt();
if (input.next().equals("\n\n"));
{
cnt++;
}
}
int big = elf[0];
for (int lcv = 0; lcv < elf.length; lcv++)
{
if (big < elf[lcv])
{
big = elf[lcv];
}
}
System.out.println(big);
}
}
I'm trying this to detect the double line break
if (input.next().equals("\n\n"));
but its giving me errors. how would i detect it
Here is another alternative way to do this sort of thing. read comments in code:
public static void main(String[] args) throws FileNotFoundException {
List<Integer> elfSums; // Can grow dynamically whereas an Array can not.
int sum;
// 'Try With Resources' used here to auto close the reader and free resources.
try (Scanner input = new Scanner(new File("Elf.dat"))) {
elfSums = new ArrayList<>();
String line;
sum = 0;
while (input.hasNextLine()) {
line = input.nextLine();
if (line.trim().isEmpty()) {
elfSums.add(sum);
sum = 0; // Reset sum to 0 (new elf comming up)
}
// Does the line contain a string representation of a integer numerical value?
if (line.matches("\\d+")) {
// Yes...add to current sum value.
sum += Integer.parseInt(line);
}
}
}
if (sum > 0) {
elfSums.add(sum);
}
// Convert List to int[] Array (There are shorter ways to do this)
int[] elf = new int[elfSums.size()];
for (int i = 0; i < elfSums.size(); i++) {
elf[i] = elfSums.get(i);
// For the heck of it, display the total sum for this current Elf
System.out.println("Elf #" + (i+1) + " Sum: -> " + elf[i]);
}
/* The elf[] int array now holds the data you need WITHOUT
all those empty elements with the array. */
}
Welcome to Advent of Code 22.
As a good rule, never mix nextXXX methods with any other next.
To break up the Blocks you have 2 good options:
Read line by line and fill a new list when you encounter a empty/blank line
Read the whole text fully, then split by the \n\n Combination

Why does this binary search code give wrong output on Eclipse IDE?

Why does this binary search code give wrong output on Eclipse IDE but gets accepted when submitted to Coursera? This is a sample input for which it shows the wrong output.
Sample Input:
5 3 2 4 1 5
3 1 2 7
Output:
-1 -1 -1
Clearly, the element '1' is present is the input array. But the output for that is -1 instead of 3.
import java.io.*;
import java.util.*;
public class BinarySearch {
static int binarySearch(int[] a,int l,int r,int x) {
//write your code here
if(l<=r){
int mid =l + (r - l)/2;
if(x==a[mid])
return mid;
else if(x<a[mid]){
return binarySearch(a,l,mid-1,x);
}
else
return binarySearch(a,mid+1,r,x);
}
return -1;
}
public static void main(String[] args) {
FastScanner scanner = new FastScanner(System.in);
int n = scanner.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
}
int m = scanner.nextInt();
int[] b = new int[m];
for (int i = 0; i < m; i++) {
b[i] = scanner.nextInt();
}
for (int i = 0; i < m; i++) {
//replace with the call to binarySearch when implemented
System.out.print(binarySearch(a,0,n-1,b[i]) + " ");
}
}
static class FastScanner {
BufferedReader br;
StringTokenizer st;
FastScanner(InputStream stream) {
try {
br = new BufferedReader(new InputStreamReader(stream));
} catch (Exception e) {
e.printStackTrace();
}
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}
Actually, the problem is with your input data and not the code itself. If you search information about binary search you can find: "binary search is a search algorithm that finds the position of a target value within a sorted array". Your input isn't sorted.
You would have to sort the array before running the search which would be a bad idea - searching with other algorithm would take less time than sorting.
If you try to input sorted data, eg.:
5 1 2 3 4 5
3 1 2 7
The result will be 0 1 -1 - just as expected.

Read text file and convert rows to Integer arrays [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 8 years ago.
Improve this question
I try to read text file such this one:
23 0 5 6
28 1 9 5 4 0 3
90 3 6 4 7
-1
I want to read and convert each row individually as integer vector and stop reading when value = -1. I get this code:
importjava.io.FileReader;
importjava.io.IOException;
importjava.util.Scanner;
public class T3 {
public static void main(String[] args) throws IOException {
FileReader file = new FileReader("e:\\test.txt");
int[] integers = new int[100];
int[] I = new int[100];
int i = 0;
try {
Scanner input = new Scanner(file);
while (input.hasNext()) {
integers[i] = input.nextInt();
i++;
}
input.close();
} catch (Exception e) {
e.printStackTrace();
}
for (i = 0; i < 10; i++) {
System.out.println(integers[i]);
}
}
}
But it is useless. Please, I need help.
Modify the while as shown below
Scanner s = new Scanner("file path");
while (s.hasNextLine()) {
//read each line in the file and split the line content on the basis of space
String[] eachLine = s.nextLine().split("\\s+");
}
Once you have the eachLine String array - use it to initialize the Integer vector. Also, following this approach you can avoid the -1 which you are putting explicitly to tell the Scanner the end of line/ file/ input.
Use eachLine.lenght to define the length of each Vector.
For example,
28 1 9 5 4 0 3
90 3 6 4 7
Scanner s = new Scanner("file path");
while (s.hasNextLine()) {
String[] eachLine = s.nextLine().split("\\s+");
//import java.util.Arrays;
System.out.println(Arrays.toString(eachLine));
}
Path path = get("test.txt");
List<int[]> list = new ArrayList<>();
try (BufferedReader reader = newBufferedReader(path)) {
String line;
while ((line = reader.readLine()) != null && !line.contains("-1")) {
if (line.isEmpty()) continue;
String[] strings = line.split(" ");
int[] integers = new int[strings.length];
for (int i = 0; i < strings.length; i++) {
integers[i] = parseInt(strings[i]);
}
list.add(integers);
}
}
Edit:
import static java.nio.file.Files.newBufferedReader;
import static java.lang.Integer.parseInt;
import static java.nio.file.Paths.get;
Lets get you on the right track.
I think the problem with your code is that you assume each next character is an integer. Which is not the case as you have spaces as delimiter.
An approach I would do is read in line by line with the nextLine method. Then use a StringTokenizer to cut all integers apart from eachother by specifying the delimiter (space in your case).
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
public class EgoStroker {
private static final String DELIMITER = " ";
private static final int MINUS_ONE = -1;
private static final String INPUT_FILE_NAME = "input.txt";
public static void main(String[] args) {
// List containing the integers read.
final List<Integer> integers = new ArrayList<>();
FileReader fileReader = null;
try {
fileReader = new FileReader(INPUT_FILE_NAME);
} catch (FileNotFoundException exc) {
exc.printStackTrace();
}
final Scanner scanner = new Scanner(fileReader);
// Boolean that will become false when -1 is encountered and
// is then used to stop the reading process.
boolean cont = true;
while(cont && scanner.hasNextLine()) {
final String line = scanner.nextLine();
final StringTokenizer tokenizer = new StringTokenizer(line, DELIMITER);
while(cont && tokenizer.hasMoreTokens()) {
final int number = Integer.parseInt(tokenizer.nextToken());
if(number == MINUS_ONE) {
cont = false;
} else {
integers.add(number);
}
}
}
int index = 0;
for(int integer : integers) {
++ index;
System.out.println(index + ". " + integer);
}
}
}
You could replace the List with an array but you don't know in advance how many objects you will have at most so its more safe to use a dynamic List.

Getting TLE in CodeChef and need for improvement of code

I am trying to solve a practice question of CodeChef . In this problem we are given N numbers Ai...An and we first have to sort(ascending order) the numbers and then add the alternate numbers starting from the last and show the output for each test cases , the test cases has 2 parts :
1>Constraints :
1 ≤ Ai ≤ 109
1 ≤ N ≤ 1000
2>Constraints:
1 ≤ Ai ≤ 109
1 ≤ N ≤ 105
You can see the full problem here.
The first part of my problem was successfully submitted but second part showed NZEC because I was using long to add those numbers(which was beyond that range). So I decided to use Strings to add up my numbers here is the method :
public static String myStringWayToAdd(String first , String second){
String temp = "";
if(first.length() < second.length()){
temp = first;
first = second;
second = temp;
}
temp = "";
int carry = 0;
for(int i=1;i<=first.length();++i){
if(i <= second.length()){
carry += Integer.parseInt(first.charAt(first.length()-i)+"") + Integer.parseInt(second.charAt(second.length()-i)+"");
}
else{
carry += Integer.parseInt(first.charAt(first.length()-i)+"");
}
temp += carry%10;
carry = carry/10;
}
if(carry != 0)
temp += carry;
StringBuilder myResult = new StringBuilder(temp);
return(myResult.reverse().toString());
}
But now it shows TLE(Time Limit Expire) , So then I thought to use BigInteger(which I am not pretty much Aware of but I saw some tutorials) :
BigInteger big = new BigInteger("0");
big = big.add(BigInteger.valueOf(mySort.get(j))); //for addition and mySort is my ArrayList
But this gave me NZEC I don't know whywell now I want to use double variable but there is a problem with that too, because with double large numbers will be in form of exponential value like :
1.243536E15 which will not be accepted by the machine, so is there any good way to solve this problem and not getting any Time Limit Expiry?.
Any help will really be appreciated. Thank you in Advance.
Edit 1 :
I changed baxck the variable to long and run and this time strangely I got TLE here is my code :
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.math.BigInteger;
import java.lang.Number;
class CFEA{
public static void main(String[] s){
Scanner scan = new Scanner(System.in);
int testCases = scan.nextInt();
for(int i = 0 ; i<testCases;++i){
long sum = 0;
//BigInteger big = new BigInteger("0");
ArrayList<Integer> mySort = new ArrayList<Integer>();
int n = scan.nextInt();
for(int j = 1 ; j <= n ; ++j){
mySort.add(scan.nextInt());
}
Collections.sort(mySort);
for(int j = mySort.size()-1 ; j >= 0 ; j=j-2){
sum += mySort.get(j);
}
System.out.println(sum);
}
}
}
And here is Link to my submission.Is there Anything I can optimize in my code?
The sum of all number is at most 10^9 * 10^5 = 10^14. It is small enough to fit into long. There is no need to use BigInteger.
java.util.Scanner has performance issues. You can implement a custom scanner(using BufferedReader) to speed up your code.
Here is my implementation of a scanner:
import java.io.*;
import java.util.StringTokenizer;
public class FastScanner {
private BufferedReader reader;
private StringTokenizer tokenizer;
public FastScanner(InputStream inputStream) {
reader = new BufferedReader(new InputStreamReader(inputStream));
}
public String next() throws IOException {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
String line = reader.readLine();
if (line == null)
throw new IOException();
tokenizer = new StringTokenizer(line);
}
return tokenizer.nextToken();
}
public int nextInt() throws IOException {
return Integer.parseInt(next());
}
public void close() {
try {
reader.close();
} catch (IOException e) {
//ignore
}
}
}
I did some changes in my Program and it was All Accepted a much relief after submitting for about 20 times , here is my new code :
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
class CFEA{
public static void main(String[] s){
Scanner scan = new Scanner(System.in);
byte testCases = Byte.parseByte(scan.nextLine()); //used byte for test cases instead of int
for(int i = 0 ; i<testCases;++i){
long sum = 0;
//BigInteger big = new BigInteger("0");
ArrayList<Integer> mySort = new ArrayList<Integer>();
int n = Integer.parseInt(scan.nextLine());
String input = scan.nextLine();
String[] my = input.split(" ");
for(String myString : my){
mySort.add(Integer.parseInt(myString));
}
Collections.sort(mySort);
for(int j = mySort.size()-1 ; j >= 0 ; j=j-2){
sum += mySort.get(j);
}
System.out.println(sum);
}
}
}
I think the main villain was that I was scanning for Integers N number of times as in this :
for(int j = 1 ; j <= n ; ++j){
mySort.add(scan.nextInt());
}
When N was something Like 100000 then this really slows it down.So i used 1 String for complete line and then Split it into Integers using split method as in :
String input = scan.nextLine(); //only 1 Scanner
String[] my = input.split(" ");
for(String myString : my){
mySort.add(Integer.parseInt(myString));
}
Although My code got submitted I still think there is Further scope for optimization , so please do answer if you have something better

Java program not outputting negative integers from array?

One of my Java assignments is to take numbers from a file and then seperate them to two arrays. One named P (positive numbers) and N (negative numbers.) I have it working for the positive numbers but the negative numbers keep outputting 0s. I have no idea why! Help?
import java.io.*;
import java.util.*;
public class Prog404a {
public static void main(String[] args) {
Scanner inFile = null;
try {
inFile = new Scanner(new File("prg404a1.dat"));
} catch (FileNotFoundException e) {
System.out.println("File not found!!");
System.exit(0);
}
int temp = 0;
int P[] = new int[23];
int N[] = new int[23];
int i = 0;
while (inFile.hasNext()) {
temp = inFile.nextInt();
if (temp < 0) {
N[i] = temp;
}
if (temp > 0) {
P[i] = temp;
}
i++;
}
for (int x = 0; x < i; x++) {
System.out.println(P[x] + "\t" + N[x]);
}
}
}
EDIT: Never mind it's not working for positive numbers either. Only a few.
Maybe you are just not counting right?
You should be using two counters, one for positive, one for negative numbers.
Otherwise, half of the entries will obviously be 0, because they were never set.

Categories

Resources