I have made a Project Euler runner in order to facilitate the running of the various problems. I have never used reflection before, and I believe that I have found a good use for reflection within this project.
My question boils down to this:
- Is this an appropriate use of reflection? Or am I approaching this the wrong way?
- Is the static import of System wrong in this case?
package ProjectEulerRunner;
import static java.lang.System.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;
public class ProjectEulerRunner
{
private static final int NUM_OF_PROBLEMS = 20;
private static final Scanner scan = new Scanner(in);
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException
{
for(;;)
{
out.println("Welcome to the Project Euler problem solver!");
out.println("==========================================================");
out.println("Total Number of Problems: " + NUM_OF_PROBLEMS);
out.println("==========================================================");
out.println();
out.println("What would you like to do?");
out.println();
out.println("(1) Run all Project Euler problems.");
out.println("(2) Run a specific problem number. Between 1 and " + NUM_OF_PROBLEMS);
out.println("(3) Get all problem descriptions.");
out.println("(4) Get a specific problem description.");
out.println("(5) View all incomplete problems");
out.println("(6) Basic problem statistics. (Percentage Correct, etc.)");
out.println("(7) Advanced problem statistics. (Average Run Times, Collated Data, etc.");
out.println("(0) Exit");
out.println();
out.print("Your choice: ");
int input = scan.nextInt();
switch(input)
{
case 0:
out.println("Exiting...");
exit(0);
break;
case 1:
out.println("Running all problems...");
runAllProblems();
break;
}
}
}
private static void runAllProblems() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException
{
for(int i = 1; i <= NUM_OF_PROBLEMS; i++)
{
Class<?> cls = null;
String num = EnglishNumberToWords.convert(i);
num = capitalize(num);
try {
cls = Class.forName("Problems.Problem" + num);
}
catch(ClassNotFoundException e) {
out.println("Problem " + EnglishNumberToWords.convert(i) + " not started yet!");
out.println();
}
if(cls != null)
{
Object obj = cls.newInstance();
Method method = cls.getDeclaredMethod("isCorrect");
Object ret = method.invoke(obj);
out.println(cls + ", Completed? (" + ret + ")");
if((boolean)ret != false)
{
method = cls.getDeclaredMethod("run");
Object run = method.invoke(obj);
out.println(run);
out.println();
}
else
{
out.println();
}
}
}
out.println("Press any key to return to the menu!");
in.read();
}
private static String capitalize(String line)
{
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
}
}
Notes:
Yeah, I know that I should be handling exceptions with more grace, but this is just to get things up and running at the moment.
The main section I am concerned about at the moment is the
runAllProblems()
method.If anyone is confused by the
Scanner(in)
or numerousout.println
's. I statically importedjava.lang.System
in order to shorten a bit of the code. Is this ok?Sadly, the code is uncommented. But I hope it is understandable. If it is not, I can comment or change things accordingly.
ArrayList<Problem> problems
as that would mean I would have to go through EVERY problem and instantiate it withx = new Problems.Problem<InsertNumberHere>
, followed byproblems.add(x)
. That is why I am trying to use reflection to avoid having to type over 400+new
statements. Avoids looping as well. Am I mad? \$\endgroup\$