Hiking around HackerRank — 05
08/01/2020
Note:
- All problems are published by HackerRank, credit to HackerRank
- The solutions are coded by myself, and open source just for study.
Java Abstract Class
Referred to Java Docs, “ an abstract class is a class that declared abstract.” What does that mean?
But if we keep reading, we will find this, “abstract classes cannot be initiated, but can be subclassed.” [1] It makes some sense, huh?
Let’s solve it!
import java.util.*;
abstract class Book{
String title;
abstract void setTitle(String s);
String getTitle(){
return title;
}
}
//Write MyBook class here
class MyBook extends Book {
void setTitle(String str) {
title = str;
}
}
public class Main{
public static void main(String []args){
//Book new_novel=new Book(); This line prHMain.java:25: error: Book is abstract; cannot be instantiated
Scanner sc=new Scanner(System.in);
String title=sc.nextLine();
MyBook new_novel=new MyBook();
new_novel.setTitle(title);
System.out.println("The title is: "+new_novel.getTitle());
sc.close();
}
}
Done!
I checked others’ solutions, and found some people used “override.” I’m not sure if it is necessary, but both of them worked.
Java Interface
Referred to this doc of W3Schools, we can know that “Interface” is some kind of similar to the abstract class. It cannot be initiated but can be overridden and implemented [2].
To be honest, although it is an exercise of “Java Interface,” I believe a programmer should be familiar with the “divisor sum” to solve this problem. Of course, it is not difficult.
import java.util.*;
interface AdvancedArithmetic{
int divisor_sum(int n);
}
//Write your code here
class MyCalculator implements AdvancedArithmetic {
public int divisor_sum(int n) {
int sum = n;
for (int i = 1; i < n; i++) {
if (n%i == 0) {
sum += i;
}
}
return sum;
}
}
class Solution{
public static void main(String []args){
MyCalculator my_calculator = new MyCalculator();
System.out.print("I implemented: ");
ImplementedInterfaceNames(my_calculator);
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.print(my_calculator.divisor_sum(n) + "\n");
sc.close();
}
/*
* ImplementedInterfaceNames method takes an object and prints the name of the interfaces it implemented
*/
static void ImplementedInterfaceNames(Object o){
Class[] theInterfaces = o.getClass().getInterfaces();
for (int i = 0; i < theInterfaces.length; i++){
String interfaceName = theInterfaces[i].getName();
System.out.println(interfaceName);
}
}
}
That’s what my code looked like. In fact, I was expecting a “Runtime Error” because I looped from 1 to n. It will take more time to finish it. Surprisingly, it passed the tests!
However, I tried to modify it further:
import java.util.*;
interface AdvancedArithmetic{
int divisor_sum(int n);
}
//Write your code here
class MyCalculator implements AdvancedArithmetic {
public int divisor_sum(int n) {
int sum = n;
for (int i = 1; i < n/2; i++) {
if (n%i == 0) {
sum += i;
}
}
return sum;
}
}
class Solution{
public static void main(String []args){
MyCalculator my_calculator = new MyCalculator();
System.out.print("I implemented: ");
ImplementedInterfaceNames(my_calculator);
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.print(my_calculator.divisor_sum(n) + "\n");
sc.close();
}
/*
* ImplementedInterfaceNames method takes an object and prints the name of the interfaces it implemented
*/
static void ImplementedInterfaceNames(Object o){
Class[] theInterfaces = o.getClass().getInterfaces();
for (int i = 0; i < theInterfaces.length; i++){
String interfaceName = theInterfaces[i].getName();
System.out.println(interfaceName);
}
}
}
I changed n to n/2. Of course, it would not pass the tests. But I’m pretty sure there’s a more efficient way to solve it!
Then I found this document:
To be honest, I’m not familiar with Big O Notation, but we can understand the intention of this script. By introducing the square root of the natural number, the time complexity reduced to O(n^(1/2)) [3]. I think the Algorithms also introduced similar topics, but I can’t remember it very accurately.
Anyway, this is an interesting practice. As we can see, there is always more than one way to reach a goal, and let’s keep trying to optimize it!
Java Method Overriding
I believe we’ve encountered “Override” multiple times, but it is the first time to introduce it formally. It allows a child class to provide a specific implementation of its parent class [4]. Like in this problem, we know there are 11 players of a soccer team. So, let’s do it!
import java.util.*;
class Sports{
String getName(){
return "Generic Sports";
}
void getNumberOfTeamMembers(){
System.out.println( "Each team has n players in " + getName() );
}
}
class Soccer extends Sports{
@Override
String getName(){
return "Soccer Class";
}
// Write your overridden getNumberOfTeamMembers method here
void getNumberOfTeamMembers() {
System.out.println( "Each team has 11 players in " + getName() );
}
}
public class Solution{
public static void main(String []args){
Sports c1 = new Sports();
Soccer c2 = new Soccer();
System.out.println(c1.getName());
c1.getNumberOfTeamMembers();
System.out.println(c2.getName());
c2.getNumberOfTeamMembers();
}
}
That’s pretty easy, isn’t it?
Java Method Overriding 2 (Super Keyword)
As we can see, in the first statement, we can get the statement from the subclass. However, the second one is from the parent class. Therefore, a “super” keyword is necessary.
Here’s my code:
import java.util.*;
import java.io.*;
class BiCycle{
String define_me(){
return "a vehicle with pedals.";
}
}
class MotorCycle extends BiCycle{
String define_me(){
return "a cycle with an engine.";
}
MotorCycle(){
System.out.println("Hello I am a motorcycle, I am "+ define_me());
String temp= super.define_me(); //Fix this line
System.out.println("My ancestor is a cycle who is "+ temp );
}
}
class Solution{
public static void main(String []args){
MotorCycle M=new MotorCycle();
}
}
Done!
Java Instanceof Keyword
That’s the provided code:
import java.util.*;
class Student{}
class Rockstar{ }
class Hacker{}
public class InstanceOFTutorial{
static String count(ArrayList mylist){
int a = 0,b = 0,c = 0;
for(int i = 0; i < mylist.size(); i++){
Object element=mylist.get(i);
if(~~Complete this line~~)
a++;
if(~~Complete this line~~)
b++;
if(~~Complete this line~~)
c++;
}
String ret = Integer.toString(a)+" "+ Integer.toString(b)+" "+ Integer.toString(c);
return ret;
}
public static void main(String []args){
ArrayList mylist = new ArrayList();
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for(int i=0; i<t; i++){
String s=sc.next();
if(s.equals("Student"))mylist.add(new Student());
if(s.equals("Rockstar"))mylist.add(new Rockstar());
if(s.equals("Hacker"))mylist.add(new Hacker());
}
System.out.println(count(mylist));
}
}
(Well, I thought “(~~Complete this line ~~)” was a typo of Bitwise operation, LOL)
“Instanceof” is used to test if a variable is an instantiation of a class. if we understand this, things would be pretty clear.
import java.util.*;
class Student{}
class Rockstar{ }
class Hacker{}
public class InstanceOFTutorial{
static String count(ArrayList mylist){
int a = 0,b = 0,c = 0;
for(int i = 0; i < mylist.size(); i++){
Object element=mylist.get(i);
if(element instanceof Student)
a++;
if(element instanceof Rockstar)
b++;
if(element instanceof Hacker)
c++;
}
String ret = Integer.toString(a)+" "+ Integer.toString(b)+" "+ Integer.toString(c);
return ret;
}
public static void main(String []args){
ArrayList mylist = new ArrayList();
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for(int i=0; i<t; i++){
String s=sc.next();
if(s.equals("Student"))mylist.add(new Student());
if(s.equals("Rockstar"))mylist.add(new Rockstar());
if(s.equals("Hacker"))mylist.add(new Hacker());
}
System.out.println(count(mylist));
}
}
Finished!
Java Iterator
As stated in the problem, iterator would help you to loop through a list. Interestingly, “iterator” sounds more technical than “looping.” [5]
Here’s my code:
import java.util.*;
public class Main{
static Iterator func(ArrayList mylist){
Iterator it=mylist.iterator();
while(it.hasNext()){
Object element = it.next();
if(element instanceof String)//Hints: use instanceof operator
break;
}
return it;
}
@SuppressWarnings({ "unchecked" })
public static void main(String []args){
ArrayList mylist = new ArrayList();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
for(int i = 0;i<n;i++){
mylist.add(sc.nextInt());
}
mylist.add("###");
for(int i=0;i<m;i++){
mylist.add(sc.next());
}
Iterator it=func(mylist);
while(it.hasNext()){
Object element = it.next();
System.out.println((String)element);
}
}
}
Aha! It worked!
As we can see, OOP is beautiful. We can extend the code without modifying it too much, and we can achieve a new feature with lines of codes. Amazing!
Conclusion:
I’ve played with “Easy” problems on HackerRank for a long time. Possibly it’s time for me to start a new adventure. But exam is coming and I would (possibly) suspend my journey for a while. Hope I can be much stronger when I come back!
Here’s my repo:
Happy coding!
References:
[1] Abstract Methods and Classes, Java Docs, retrieved from https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html#:~:text=An%20abstract%20class%20is%20a,but%20they%20can%20be%20subclassed.&text=When%20an%20abstract%20class%20is,methods%20in%20its%20parent%20class.
[2] Java Interface, W3Schools, retrieved from https://www.w3schools.com/java/java_interface.asp
[3] Sum of all proper divisors of a natural number, GeeksforGeeks, retrieved from https://www.geeksforgeeks.org/sum-of-all-proper-divisors-of-a-natural-number/
[4] Overriding in Java, GeeksforGeeks, retrieved from https://www.geeksforgeeks.org/overriding-in-java/
[5] Java Iterators, W3Schools, retrieved from https://www.w3schools.com/java/java_iterator.asp#:~:text=Previous%20Next%20%E2%9D%AF-,Java%20Iterator,util%20package.