HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

HackerRank Angry Professor challenge

Submitted by: @import:stackexchange-codereview··
0
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)

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:

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.