I have been testing my code for the overlapping rectangles challenge on codeeval. I feel my code is close to the solution as I have tested it on my machine and it appears correct. Codeeval is picky however and won't execute the code, claiming it is hanging.No further information is given. It has done this in the past but that was due to me not closing my scanner at the end. Am I violating a similar principle here?
Any recommendations on finding the solution simpler or better coding practices is appreciated.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("C:/Users/minda_000/Desktop/text.txt");
FileReader fr = new FileReader(file);
Scanner scan = new Scanner(fr);
scan.useDelimiter(",");
boolean flag = true;
while (scan.hasNextLine()) {
String line = scan.nextLine();
Scanner scanline = new Scanner(line);
scanline.useDelimiter(",");
int lxa = scanline.nextInt();
int lya = scanline.nextInt();
int rxa = scanline.nextInt();
int rya = scanline.nextInt();
int lxb = scanline.nextInt();
int lyb = scanline.nextInt();
int rxb = scanline.nextInt();
int ryb = scanline.nextInt();
int[] contentsofx = contentsOfX(lxa, rxa);
int[] contentsofy = contentsOfY(lya, rya);
int[] contentsofx2 = contentsOfX(lxb, rxb);
int[] contentsofy2 = contentsOfY(lyb, ryb);
scanline.close();
for (int i = 0; i < contentsofx.length; i++) {
for (int j = 0; j < contentsofx2.length; j++) {
if (contentsofx[i] == contentsofx2[j]) {
if(i<contentsofy.length && i<contentsofy2.length && contentsofy[i]==contentsofy2[j]){
System.out.println(true);
flag=false;
}
}
}
}
if(flag) {
System.out.println(false);
}
flag=true;
}
scan.close();
}
public static int[] contentsOfX(int lx, int rx) {
int[] line = new int[(rx - lx)];
for (int i = 0; i < line.length; i++) {
line[i] = lx + i;
}
return line;
}
public static int[] contentsOfY(int ly, int ry) {
int[] line = new int[(ly - ry)];
for (int i = 0; i < line.length; i++) {
line[i] = ry + i;
}
return line;
}
}
Just to make sure, you are changing "C:/Users/minda_000/Desktop/text.txt" to args[0] before uploading your solution to CodeEval, right?
Some of the other issues:
You're outputting True and False in lowercase when they're supposed to be capitalized.
In this line --
if(i<contentsofy.length && i<contentsofy2.length && contentsofy[i]==contentsofy2[j]){
-- you've got a problem when i and/or j are larger than the lengths of contentsofy and contentsofy2.
And comments would make your code easier to read. :-)
I scrapped this code and started over more or less with a much cleaner solution just using boolean logic. The problems with this code is the contentsOfX and contentsOfY methods should be 1 size greater for one point overlap. Additionally, at this time I implied one rectangle would always be to the left of the other. The nested for loop does not work as intended because of this. Still the arrays are sorted for each value from minimum value of x,y to maximum value of x,y so if you check for the reverse polarity index within the array as well the logic should be the work.
Related
I tried to write a code that finds NashEquilibrium in given matrix.
I was keep getting errors that says I can't call non static method from static method so I turned every method and instance variable to static, is that a problem?
There are tons of logic errors in my code and it gives wrong answer, could it be because they are all static or its only logic error?
import java.util.ArrayList;
import java.util.Scanner;
public class Nash
{
public static String nes;
public static String str;
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the amount of strategies for each player");
int stratA = scan.nextInt();
int stratB = scan.nextInt();
String[][] utilities = new String[stratA][stratB];
System.out.println("Please enter the utilities");
for(int row = 0; row<stratA; row++)
for(int column = 0; column<stratB; column++)
utilities[row][column] = scan.next();
// Creates a 2D array with given utilities
if (nashExists(stratA, stratB, utilities) == true)
System.out.println(nes);
else
System.out.println("No NE found");
// Prints the results
}
public static boolean nashExists(int strA, int strB, String[][] util)
{
int[][] movesA = new int[strA][strB];
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
movesA[row][column] = Integer.parseInt(util[row][column].substring(0,1));
int[][] movesB = new int[strA][strB];
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
movesA[row][column] = Integer.parseInt(util[row][column].substring(2,3));
// Creates a 2d integer array for utilites of every strategy of A and B
ArrayList<String> aNE = new ArrayList<String>();
ArrayList<String> bNE = new ArrayList<String>();
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
if (nashExistsA(row, column, movesA) == true)
aNE.add((row+1) + "," + (column+1));
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
if (nashExistsB(row, column, movesB) == true)
bNE.add((row+1) + "," + (column+1));
// Checks if there are NE for one of players
if (compareArrayLists(aNE, bNE) == true)
return true;
else
return false;
}
// Checks if there are any matchs between both players NE's
public static boolean nashExistsA(int r, int c, int[][] a)
{
int max = a[r][c];
for (int i = 0; i<a.length; i++)
if (max < a[i][c])
max = a[i][c];
if (a[r][c] == max)
return true;
else
return false;
}
public static boolean nashExistsB(int r, int c, int[][] b)
{
int max = b[r][c];
for (int i = 0; i<b[0].length; i++)
if (max < b[r][i])
max = b[r][i];
if (b[r][c] == max)
return true;
else
return false;
}
public static boolean compareArrayLists(ArrayList<String> aN, ArrayList<String> bN)
{
for (int i=0; i<aN.size(); i++)
{
String potNE = aN.get(i);
if (bN.indexOf(potNE) >= 0)
str += "(" + potNE + ") ";
}
nes = str;
if (str.length()>0)
return true;
else
return false;
}
}
Turning members (methods and fields) into static is the classic mistake that novices tend to make when learning their first object-oriented language.
Don't do this.
I have seen this happening twice in workplaces where we hired fresh college graduates who had practically no programming experience. Predictably, after struggling with it for a while, the colleague would come to one of the older guys asking for help, and the help invariably was "lose static everywhere".
The more things you turn into static, the less object-oriented you are; if you turn everything static, then you are not object-oriented at all; you might as well be programming in BASIC or in COBOL.
When you become more familiar with the language and you start doing more advanced stuff, you will discover legitimate uses for static, which are very rare. When you come across such a situation, you will know it. Until then, stick with the rule that says:
Generally, avoid static like the plague.
Hello I've been getting this error in Kattis, 'Run time error' while all my test cases are correct in my own machine. Tested everything but as soon as i run this in kattis i get a run time error. Can you guys help me figure this out? Ive been debugging for hours but i am struggling.
https://open.kattis.com/problems/throwns?editsubmit=9372235 :Link of the problem
import java.util.*;
import java.io.*;
public class GOT{
public static void main(String[] args)throws IOException{
BufferedReader bi = new BufferedReader(new I
nputStreamReader(System.in));
int[] parseLine1 = new int[2];
String[] strLine1;
strLine1 = bi.readLine().split(" ");
//Parsing of 1st line of inputs i.e. N and K
for (int i = 0; i < strLine1.length; i++) {
parseLine1[i] = Integer.parseInt(strLine1[i]);
}
//init of Kids array
int[] nKids = new int[parseLine1[0]];
String[] commands = new String[parseLine1[1]];
int i;
for(i = 0; i < nKids.length; i++){
nKids[i] = i;
}
//parsing of 2nd line which are the commands
String strLine2;
String[] nCommands;
Scanner sc = new Scanner(System.in);
strLine2 = sc.nextLine();
nCommands = strLine2.split(" ");
int holder=0;
ArrayList<Integer> tracker = new ArrayList<Integer>();
int exit;
int throwns;
int undoCtr=0;
for(i = 0; i<nCommands.length; i++){
if(nCommands[i].equals("undo")){
nCommands[i] = nCommands[i].replaceAll("undo","101");
}
}
exit = nCommands.length;
i = 0;
while(exit != 0){
//System.out.println(Integer.parseInt(nCommands[i]));
if(Integer.parseInt(nCommands[i]) > 0){
for(int k = 0; k< Integer.parseInt(nCommands[i]); k++){
holder++;
if(holder==nKids.length){
holder = 0;
}
}
}if(Integer.parseInt(nCommands[i]) < 0){
for(int k = Integer.parseInt(nCommands[i]); k<0 ; k++){
holder--;
if(holder==0){
holder = nKids.length;
}
}
}else if(Integer.parseInt(nCommands[i]) == 101){
i++;
undoCtr = Integer.parseInt(nCommands[i]);
while(undoCtr!=0){
tracker.remove(tracker.size()-1);
undoCtr--;
}
exit--;
}
tracker.add(holder);
exit--;
i++;
}
System.out.println(tracker.get(0));
}`
}`
Your approach is too complex for a 2.8 difficulty problem. If you find yourself writing more than 25 lines of code, it's usually time to take a step back and re-think your approach.
Here's the algorithm that worked for me:
Make a list of "final" throw commands, initially empty.
Loop over the input tokens and analyze each command:
If a command is a number, append to the command list.
If a command is an undo n, pop the command list n times.
Now sum the commands in the list and print the mod of this sum, taking care to keep the mod positive.
Here's the spoiler:
public class Throwns {
public static void main(String[] args) {
var sc = new java.util.Scanner(System.in);
int n = Integer.parseInt(sc.nextLine().split(" ")[0]);
var line = sc.nextLine().split(" ");
var commands = new java.util.ArrayList<Integer>();
int sum = 0;
for (int i = 0; i < line.length; i++) {
if (line[i].matches("^-?\\d+$")) {
commands.add(Integer.parseInt(line[i]));
continue;
}
for (int j = Integer.parseInt(line[++i]); j > 0; j--) {
commands.remove(commands.size() - 1);
}
}
for (int c : commands) {
sum += c;
}
System.out.println(Math.floorMod(sum, n));
}
}
Even if I think that I solved a competitive programming problem from HackerEarth with the best approach, all tests exceed the time limit. I really do not know how to optimize it further because it is just an easy exercise.
My approach: iterate over all array members than add them to a HashMap which stores their occurrences. After that simply read the query numbers and get their occurence from the HashMap.
This is my solution:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
class TestClass {
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
//go through all test cases
for (int i = 0; i < t; i++) {
Map<Integer, Integer> map = new HashMap<>();
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int Q = Integer.parseInt(inputs[1]);
inputs = br.readLine().split(" ");
//read array
for (int j = 0; j < N; j++) {
int x = Integer.parseInt(inputs[j]);
Integer value = map.get(x);
//if number is already in hashmap then increment its count
//else put it into the map with a count of 1
if (value == null) {
map.put(x, 1);
} else map.put(x, value + 1);
}
//iterate through the queries and get their occurences from the map
for (int j = 0; j < Q; j++) {
int x = Integer.parseInt(br.readLine());
Integer value = map.get(x);
if (value == null) {
System.out.println(0);
} else System.out.println(value);
}
}
}
}
My question is: what can be the problem with my approach? Why does it run out of time?
Ok, so the problem is not so obvious. I took a look at the input files and they are huge so you have to use some really fast method for writing to the console(many test cases -->> many answers). You can use PrinteWriter for that.
Working solution:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
class TestClass {
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pr = new PrintWriter(System.out);
int t = Integer.parseInt(br.readLine());
//go through all test cases
for (int i = 0; i < t; i++) {
Map<Integer, Integer> map = new HashMap<>();
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int Q = Integer.parseInt(inputs[1]);
inputs = br.readLine().split(" ");
//read array
for (int j = 0; j < N; j++) {
int x = Integer.parseInt(inputs[j]);
Integer value = map.get(x);
//if number is already in hashmap then increment its count
//else put it into the map with a count of 1
if (value == null) {
map.put(x, 1);
} else map.put(x, value + 1);
}
//iterate through the queries and get their occurences from the map
for (int j = 0; j < Q; j++) {
int x = Integer.parseInt(br.readLine());
Integer value = map.get(x);
if (value == null) {
pr.println(0);
} else pr.println(value);
}
}
pr.close();
}
}
Yes, I know that it is strange that the exercise itself is not so hard, but reading the input and writing the result is the big part of it.
The problem with your approach is primarily it's use of BufferedReader, and the consequential information parsing you're preforming. Try an approach with scanner.
import java.util.*;
class TestClass {
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
int T = s.nextInt();
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i=0;i<T;i++)
{
StringBuilder sb=new StringBuilder();
int N=s.nextInt();
int Q=s.nextInt();
int[] arr=new int[N];
for(int j=0;j<N;j++)
{
arr[j]=s.nextInt();
if(map.containsKey(arr[j]))
{
map.put(arr[j],map.get(arr[j])+1);
}
else
map.put(arr[j],1);
}
for(int k=0;k<Q;k++)
{
int X=s.nextInt();
if(map.containsKey(X)){
sb.append(map.get(X)+"\n");
}
else{
sb.append(0+"\n");
}
}
System.out.println(sb.toString());
map.clear();
}
}
}
This will remove a lot of the unnecessary parsing you are doing with:
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int Q = Integer.parseInt(inputs[1]);
inputs = br.readLine().split(" ");
Please look at Scanner vs. BufferedReader to understand why Scanner is situationally faster here. Essentially BufferedReader is faster in it's ability to simply read the lines, but when you use BufferedReader here, you are then forced to use Integer.parseInt(...) and br.readlines().split(" ") to parse the information you need from the input; however, scanner has built in parsing mechanisms that can read and parse the data asynchronously. As you will see, this approach passes the test in 4-8 seconds. Additionally you could benefit from using StringBuilder, and not using:
Integer value = map.get(x);
if (value == null) {
pr.println(0);
} else pr.println(value);
With the built in method map.containsKey(x).
Scanner is used for parsing tokens from the contents of the stream while BufferedReader just reads the stream and does not do any special
parsing.
In fact you can pass a BufferedReader to a scanner as the source of
characters to parse.
Furthermore:
A scanner on the other hand has a lot more cheese built into it; it
can do all that a BufferedReader can do and at around the same level of
efficiency as well. However, in addition a Scanner can parse the
underlying stream for primitive types and strings using regular
expressions. It can also tokenize the underlying stream with the
delimiter of your choice. It can also do forward scanning of the
underlying stream disregarding the delimiter!
There is a large difference in runtime when you have to call
inputs = br.readLine().split(" "); and Integer.parseInt(..) multiple times, versus simply calling s.nextInt(). You are already reading the data with br.readLine(), when you call Integer.parseInt(...) the data is read again by the parseInt() function.
So I made this to print primes between two numbers of my choice; however, it prints out a comma after the last number and I don't know how to take it off.
Example
in: 0 10
out: 2, 3, 5, 7,
I want 2,3,5,7
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){System.out.printf("%d,", i);}
}
}
Use a boolean to keep track of whether you've printed anything yet. Then your format string could be something like
anythingPrinted ? ",%d" : "%d"
That is, only include the comma in the format string if there's something printed.
Use a StringBuilder and write to the console at the end of your program.
StringBuilder sb = new StringBuilder();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){
// If the length of the StringBuilder is 0, no need for a comma
if(sb.length() != 0) {
sb.append(",");
}
sb.append(i);
}
}
System.out.println(sb);
This might seem like overkill, and for many cases it might be, but I have been writing a source code transcoder and I find this situation coming up a lot. Where I need commas in between values, or a prefix value which is only printed once. So I found it handy to create a class which simplifies things.
Again, you wouldn't probably want to use this if you code had one or two print loops in it, but maybe if you had more than a few. Perhaps you would remove in "on first" part if you were never going to use it.
public class FirstPrintOptions {
private PrintStream printStream;
private String onFirst;
private String remaining;
private boolean trip = false;
public FirstPrintOptions(PrintStream printStream, String onFirst, String remaining) {
this.printStream = printStream;
this.onFirst = onFirst;
this.remaining = remaining;
}
public void print() {
if (!trip) {
if (onFirst != null) {
printStream.print(onFirst);
}
trip = true;
} else {
if (remaining != null) {
printStream.print(remaining);
}
}
}
}
Then use it like this..
FirstPrintOptions firstPrintOptions = new FirstPrintOptions(System.out, null, ",");
for (int x=0;x<10;x++) {
firstPrintOptions.print();
System.out.print(x);
}
The results are..
0,1,2,3,4,5,6,7,8,9
I was testing and I came up with this. I was using compilejava.net so scanner doesn't work. I bypassed that part and just set a and b manually. Basically, it builds a string with the numbers and ends in a comma. Then it prints a substring including everything except the last comma.
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
//Scanner s = new Scanner(System.in);
int a = 2;
int b = 18;
String c = "Output = ";
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){c=c+ Integer.toString(i) + ",";}
}
System.out.print(c.subSequence(0, c.length()-1));
}
}
this program for finding factors of a number
for(i=1;i<=number;i++)
{
if(number%i==0)
{
system.out.print(i);
if(i!=0)
{system.out.print(",");}
}
}
so i get the output for 10 as
1,2,5,10
I want to read and save the content of the file in a 2d array, but I don't know the size of the file, because the program should read different files. So there is the first problem after "new char". I searched for the problem and found that "matrix[x][y]=zeile.charAt(x);"
should be right, but that throws the error "NullPointerException" when I write any number into the first brackets of new char.
Could somebody explain and give some ideas oder solutions? Thank you :)
import java.io.*;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
String zeile = br.readLine();
char [][] matrix = new char [][];
while(zeile != null )
{
int y = 0;
for(int x = 0; x < zeile.length(); x++) {
matrix[x][y] = zeile.charAt(x);
}
y++;
} System.out.print(matrix);
br.close();
}
}
Arrays are stored as blocks in memory in order to achieve O(1) operations, which is why you need to define their size during definition. If you insist on arrays (rather than a dynamic ADT such as List), you'll need to know the dimensions in advance.
What you could do is store the file lines temporarily in a list and find out the maximum line length, i.e.:
List<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char[][] matrix = new char[lines.length()][max];
// populate the matrix:
for (int i = 0; i < lines.length(); i++) {
String line = lines.get(i);
for (int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
}
}
Note that since char is a primitive, you'll be initialized with the default value 0 (the integer, not the character!) in every cell of the inner array, so for lines which are shorter than the others, you'll have trailing zero characters.
you initialize the matrix (char [][]) but you never initialize any of the inbound arrays. This leads to the NullPointerException.
In addition your 'while' condition looks invalid, seems you only are reading the first line of your file here > your code will never complete and read the first line over and over again
Thank you all! It works! But there is still one problem. I changed lines.length() into lines.size(), because it doesn't work with length. The problem is the output. It shows for example: xxxx xxxx instead of "xxx" and "x x" and "xxx" among each other.
How can I build in a line break?
my programcode is:
import java.io.*;
import java.util.ArrayList;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
ArrayList<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char [][] matrix = new char[lines.size()][max];
for(int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
for(int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
System.out.print(matrix[i][j]);
}
}
br.close();
}
}