patternjavaMinor
HackerRank Angry Professor challenge
Viewed 0 times
hackerrankangryprofessorchallenge
Problem
I've written an answer to HackerRank's Angry Professor problem. Please let me know if there's a quicker/better way of solving this as I think I wrote quite a bit of code for this problem (answer has to be in 1 class btw). Also, any improvements on my code in Java 8 are welcome too.
Problem statement (as written on HackerRank):
The professor is conducting a course on Discrete Mathematics to a
class of N students. He is angry at the lack of their discipline, and
he decides to cancel the class if there are less than K students
present after the class starts.
Given the arrival time of each student, your task is to find out if
the class gets cancelled or not.
Answer:
```
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class AngryProfessor {
public static void main(String[] args) {
List>> testCases = readInput();
for(List> testCase : testCases){
int numStudents = testCase.get(0).get(0);
int minStudents = testCase.get(0).get(1);
// Gotta STDOUT in hacker rank for it to be graded.
System.out.println(isLectureCancelled(calcNumAttending(testCase.get(1), numStudents), minStudents));
}
}
private static void addData(List arrayList, String[] numbersToAdd){
for(String num : numbersToAdd){
arrayList.add(Integer.valueOf(num));
}
}
/**
* Calculates the number of students that make the lecture on time.
*
* @param studentTimes the relative time at which the student arrives (student is on time if time is studentTimes, int numStudents){
int numAttending = 0;
for(int i = 0; i >> readInput(){
Scanner k = new Scanner(System.in);
int numTestCases = Integer.valueOf(k.nextLine());
List>> testCases = new ArrayList<>(numTestCases);
// fills up testCases with ArrayLists before filling up with numbers
for(int i = 0; i > list = new ArrayList<>(2)
Problem statement (as written on HackerRank):
The professor is conducting a course on Discrete Mathematics to a
class of N students. He is angry at the lack of their discipline, and
he decides to cancel the class if there are less than K students
present after the class starts.
Given the arrival time of each student, your task is to find out if
the class gets cancelled or not.
Answer:
```
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class AngryProfessor {
public static void main(String[] args) {
List>> testCases = readInput();
for(List> testCase : testCases){
int numStudents = testCase.get(0).get(0);
int minStudents = testCase.get(0).get(1);
// Gotta STDOUT in hacker rank for it to be graded.
System.out.println(isLectureCancelled(calcNumAttending(testCase.get(1), numStudents), minStudents));
}
}
private static void addData(List arrayList, String[] numbersToAdd){
for(String num : numbersToAdd){
arrayList.add(Integer.valueOf(num));
}
}
/**
* Calculates the number of students that make the lecture on time.
*
* @param studentTimes the relative time at which the student arrives (student is on time if time is studentTimes, int numStudents){
int numAttending = 0;
for(int i = 0; i >> readInput(){
Scanner k = new Scanner(System.in);
int numTestCases = Integer.valueOf(k.nextLine());
List>> testCases = new ArrayList<>(numTestCases);
// fills up testCases with ArrayLists before filling up with numbers
for(int i = 0; i > list = new ArrayList<>(2)
Solution
you have a nice, correct program here!
...please see what I made of it with little scope on "fewer lines" and little "performance" and of course some Java8 tweaks:
...please see what I made of it with little scope on "fewer lines" and little "performance" and of course some Java8 tweaks:
import java.util.LinkedList;//why always Array-Array?(especially for 2 - 20 entries)
import java.util.List;
import java.util.Scanner;
public class Solution {//adjusted class name for code upload
public static void main(String[] args) {
readInput()// don't need the variable, but same call as in original program
.stream().forEach(//just as a showcase for streams and lambda but no real improvement
/*TestCase*/ t -> {System.out.println(t.outcome);}
);
}
private static List readInput() {//no changes, except the return (list) type
final List testCases = new LinkedList<>();//"final" becuase it is..., LinkedList: no(0) initial capacity
try (Scanner k = new Scanner(System.in)) {//try with ressources {@link: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html}
int numTestCases = Integer.valueOf(k.nextLine());//original code
for (int i = 0; i list, when knowing the size in advance and size < 65536 (2^16)
//we only need this:
final String outcome;
private TestCase(String courseData, String studsData) {
/*This is the "power" but also "the weakness" of this approach:
It does everything (possible) in one loop/line/routine -
it saves lines of code (and maybe little exec. time)!
But it is less flexible, and for big routines
(many students, and maybe not "keyboard scanner")
this would definitely be a bottleneck.*/
String[] tmp = courseData.split(" ");//according to original code, reuse of String[] variable
students = Integer.valueOf(tmp[0]);//according to original code/input format
minAttendees = Integer.valueOf(tmp[1]);//...
tmp = studsData.split(" ");//...
arrivals = new int[students];//..initialize...
int attendees = 0;//...
for (int i = 0; i < students; i++) {//only one loop...
arrivals[i] = Integer.valueOf(tmp[i]);//...copying...
if (arrivals[i] <= 0) {//...evaluating...
attendees++;
}
}
outcome = attendees < minAttendees ? "YES" : "NO";//..and finally aggregating
}
}
}Code Snippets
import java.util.LinkedList;//why always Array-Array?(especially for 2 - 20 entries)
import java.util.List;
import java.util.Scanner;
public class Solution {//adjusted class name for code upload
public static void main(String[] args) {
readInput()// don't need the variable, but same call as in original program
.stream().forEach(//just as a showcase for streams and lambda but no real improvement
/*TestCase*/ t -> {System.out.println(t.outcome);}
);
}
private static List<TestCase> readInput() {//no changes, except the return (list) type
final List<TestCase> testCases = new LinkedList<>();//"final" becuase it is..., LinkedList: no(0) initial capacity
try (Scanner k = new Scanner(System.in)) {//try with ressources {@link: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html}
int numTestCases = Integer.valueOf(k.nextLine());//original code
for (int i = 0; i < numTestCases; i++) {//...
testCases.add(//...
new TestCase(//new "TestCase" with ...
k.nextLine(),//the next line <- blocks
k.nextLine() //..and the next line <-blocks
)
);
}
}
return testCases;
}
private static class TestCase {//This is "nicer" to read/understand than nested lists
//we don't really need these (they could also be local constructor variables):
private final int students;
private final int minAttendees;
private final int[] arrivals;//(I) prefer arrays>list, when knowing the size in advance and size < 65536 (2^16)
//we only need this:
final String outcome;
private TestCase(String courseData, String studsData) {
/*This is the "power" but also "the weakness" of this approach:
It does everything (possible) in one loop/line/routine -
it saves lines of code (and maybe little exec. time)!
But it is less flexible, and for big routines
(many students, and maybe not "keyboard scanner")
this would definitely be a bottleneck.*/
String[] tmp = courseData.split(" ");//according to original code, reuse of String[] variable
students = Integer.valueOf(tmp[0]);//according to original code/input format
minAttendees = Integer.valueOf(tmp[1]);//...
tmp = studsData.split(" ");//...
arrivals = new int[students];//..initialize...
int attendees = 0;//...
for (int i = 0; i < students; i++) {//only one loop...
arrivals[i] = Integer.valueOf(tmp[i]);//...copying...
if (arrivals[i] <= 0) {//...evaluating...
attendees++;
}
}
outcome = attendees < minAttendees ? "YES" : "NO";//..and finally aggregating
}
}
}Context
StackExchange Code Review Q#86030, answer score: 3
Revisions (0)
No revisions yet.