package com.euler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Config {

    private static interface ProblemLoader {
        public Problem load();
    }

    private static final Map<String,ProblemLoader> LOADERS = new HashMap<>();
    {
        // TODO This is a pain to maintain. Can we use ClassLoader magic?
        LOADERS.put("24", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem24();
            }
        });
        LOADERS.put("27", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem27();
            }
        });
        LOADERS.put("28", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem28();
            }
        });
        LOADERS.put("29", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem29();
            }
        });
        LOADERS.put("29a", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem29a();
            }
        });
        LOADERS.put("30", new ProblemLoader() {
            @Override
            public Problem load() {
                return new Problem30();
            }
        });
    }

    private static Problem loadProblem(String key) {
        ProblemLoader loader = LOADERS.get(key);
        if (loader == null) {
            // TODO Print a list of known problems then.
            throw new IllegalArgumentException(
                "Not a known problem: "+key);
        }
        return loader.load();
    }

    private final String[] args;

    public Config(String[] args) {
        this.args = args;
    }

    public Map<String,Problem> getProblems() {
        Map<String,Problem> result = new TreeMap<>();
        for (int i = 0; i < args.length; ++i) {
            String key = args[i];
            result.put(key, loadProblem(key));
        }
        return result;
    }

}

package com.euler;

import java.util.Map;
import java.util.TreeMap;

public class Config {

    private final String[] args;

    public Config(String[] args) {
        this.args = args;
    }

    public Map<String,Problem> getProblems() {
        Map<String,Problem> result = new TreeMap<>();
        for (int i = 0; i < args.length; ++i) {
            String key = args[i];
            result.put(key, loadProblem(key));
        }
        return result;
    }

    private Problem loadProblem(String key) {
        try {
            String classPath = "com.euler.Problem" + key;
            Class cls = Class.forName(classPath);
            Object obj = cls.newInstance();
            return (Problem)obj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Use Class.forName to load problems
Use Class.forName to load problems

Saves having to maintain a mapping of problem key to classes.
