Top notch code



  • This gem of a class was written by a winner of one of those TopCoder challenges.  So you know this is solid code!  Why would anyone bother with a database (such a fad) when you can just store all the data in Java?  I also commend the completeness - each state is listed 4 times, rather than replacing the last 100 lines with:

        for (State state : stateList) {
            codesToStates.put(state.getCode(), state);
            namesToStates.put(state.getName(), state);
        }

    Iterators are for slackers.  The Country class is even better, since it has about 250 countries listed 4 times each; that's over 1000 lines of code!  Too much for me to post, so I present instead the State class.

    ===================================================   
    public static class State implements Comparable {
        private String code;
        private String name;

        public State(String code, String name) {
            this.code = code;
            this.name = name;
        }

        public String getCode() {
            return code;
        }

        public String getName() {
            return name;
        }

        public static State getStateForCode(String stateCode) {
            return codesToStates.get(stateCode);
        }

        public static State getStateForName(String stateName) {
            return namesToStates.get(stateName);
        }

        public static List<State> getStates() {
            return stateList;
        }

        public int compareTo(Object o) {
            if (!(o instanceof State)) {
                throw new ClassCastException("not a State");
            }
            State that = (State) o;
            return this.getName().compareTo(that.getName());
        }

        public static final State AK = new State("AK", "Alaska");
        public static final State AL = new State("AL", "Alabama");
        public static final State AR = new State("AR", "Arkansas");
        public static final State AZ = new State("AZ", "Arizona");
        public static final State CA = new State("CA", "California");
        public static final State CO = new State("CO", "Colorado");
        public static final State CT = new State("CT", "Connecticut");
        public static final State DC = new State("DC", "District of Columbia");
        public static final State DE = new State("DE", "Delaware");
        public static final State FL = new State("FL", "Florida");
        public static final State GA = new State("GA", "Georgia");
        public static final State HI = new State("HI", "Hawaii");
        public static final State IA = new State("IA", "Iowa");
        public static final State ID = new State("ID", "Idaho");
        public static final State IL = new State("IL", "Illinois");
        public static final State IN = new State("IN", "Indiana");
        public static final State KS = new State("KS", "Kansas");
        public static final State KY = new State("KY", "Kentucky");
        public static final State LA = new State("LA", "Louisiana");
        public static final State MA = new State("MA", "Massachusetts");
        public static final State MD = new State("MD", "Maryland");
        public static final State ME = new State("ME", "Maine");
        public static final State MI = new State("MI", "Michigan");
        public static final State MN = new State("MN", "Minnesota");
        public static final State MO = new State("MO", "Missouri");
        public static final State MS = new State("MS", "Mississippi");
        public static final State MT = new State("MT", "Montana");
        public static final State NC = new State("NC", "North Carolina");
        public static final State ND = new State("ND", "North Dakota");
        public static final State NE = new State("NE", "Nebraska");
        public static final State NH = new State("NH", "New Hampshire");
        public static final State NJ = new State("NJ", "New Jersey");
        public static final State NM = new State("NM", "New Mexico");
        public static final State NV = new State("NV", "Nevada");
        public static final State NY = new State("NY", "New York");
        public static final State OH = new State("OH", "Ohio");
        public static final State OK = new State("OK", "Oklahoma");
        public static final State OR = new State("OR", "Oregon");
        public static final State PA = new State("PA", "Pennsylvania");
        public static final State RI = new State("RI", "Rhode Island");
        public static final State SC = new State("SC", "South Carolina");
        public static final State SD = new State("SD", "South Dakota");
        public static final State TN = new State("TN", "Tennessee");
        public static final State TX = new State("TX", "Texas");
        public static final State UT = new State("UT", "Utah");
        public static final State VA = new State("VA", "Virginia");
        public static final State VT = new State("VT", "Vermont");
        public static final State WA = new State("WA", "Washington");
        public static final State WI = new State("WI", "Wisconsin");
        public static final State WV = new State("WV", "West Virginia");
        public static final State WY = new State("WY", "Wyoming");

        private static final List<State> stateList = new ArrayList<State>();
        private static final Map<String, State> codesToStates = new HashMap<String, State>();
        private static final Map<String, State> namesToStates = new HashMap<String, State>();

        static {
            stateList.add(State.AK);
            stateList.add(State.AL);
            stateList.add(State.AR);
            stateList.add(State.AZ);
            stateList.add(State.CA);
            stateList.add(State.CO);
            stateList.add(State.CT);
            stateList.add(State.DC);
            stateList.add(State.DE);
            stateList.add(State.FL);
            stateList.add(State.GA);
            stateList.add(State.HI);
            stateList.add(State.IA);
            stateList.add(State.ID);
            stateList.add(State.IL);
            stateList.add(State.IN);
            stateList.add(State.KS);
            stateList.add(State.KY);
            stateList.add(State.LA);
            stateList.add(State.MA);
            stateList.add(State.MD);
            stateList.add(State.ME);
            stateList.add(State.MI);
            stateList.add(State.MN);
            stateList.add(State.MO);
            stateList.add(State.MS);
            stateList.add(State.MT);
            stateList.add(State.NC);
            stateList.add(State.ND);
            stateList.add(State.NE);
            stateList.add(State.NH);
            stateList.add(State.NJ);
            stateList.add(State.NM);
            stateList.add(State.NV);
            stateList.add(State.NY);
            stateList.add(State.OH);
            stateList.add(State.OK);
            stateList.add(State.OR);
            stateList.add(State.PA);
            stateList.add(State.RI);
            stateList.add(State.SC);
            stateList.add(State.SD);
            stateList.add(State.TN);
            stateList.add(State.TX);
            stateList.add(State.UT);
            stateList.add(State.VA);
            stateList.add(State.VT);
            stateList.add(State.WA);
            stateList.add(State.WI);
            stateList.add(State.WV);
            stateList.add(State.WY);
            Collections.sort(stateList);

            codesToStates.put(State.AK.getCode(), State.AK);
            codesToStates.put(State.AL.getCode(), State.AL);
            codesToStates.put(State.AR.getCode(), State.AR);
            codesToStates.put(State.AZ.getCode(), State.AZ);
            codesToStates.put(State.CA.getCode(), State.CA);
            codesToStates.put(State.CO.getCode(), State.CO);
            codesToStates.put(State.CT.getCode(), State.CT);
            codesToStates.put(State.DC.getCode(), State.DC);
            codesToStates.put(State.DE.getCode(), State.DE);
            codesToStates.put(State.FL.getCode(), State.FL);
            codesToStates.put(State.GA.getCode(), State.GA);
            codesToStates.put(State.HI.getCode(), State.HI);
            codesToStates.put(State.IA.getCode(), State.IA);
            codesToStates.put(State.ID.getCode(), State.ID);
            codesToStates.put(State.IL.getCode(), State.IL);
            codesToStates.put(State.IN.getCode(), State.IN);
            codesToStates.put(State.KS.getCode(), State.KS);
            codesToStates.put(State.KY.getCode(), State.KY);
            codesToStates.put(State.LA.getCode(), State.LA);
            codesToStates.put(State.MA.getCode(), State.MA);
            codesToStates.put(State.MD.getCode(), State.MD);
            codesToStates.put(State.ME.getCode(), State.ME);
            codesToStates.put(State.MI.getCode(), State.MI);
            codesToStates.put(State.MN.getCode(), State.MN);
            codesToStates.put(State.MO.getCode(), State.MO);
            codesToStates.put(State.MS.getCode(), State.MS);
            codesToStates.put(State.MT.getCode(), State.MT);
            codesToStates.put(State.NC.getCode(), State.NC);
            codesToStates.put(State.ND.getCode(), State.ND);
            codesToStates.put(State.NE.getCode(), State.NE);
            codesToStates.put(State.NH.getCode(), State.NH);
            codesToStates.put(State.NJ.getCode(), State.NJ);
            codesToStates.put(State.NM.getCode(), State.NM);
            codesToStates.put(State.NV.getCode(), State.NV);
            codesToStates.put(State.NY.getCode(), State.NY);
            codesToStates.put(State.OH.getCode(), State.OH);
            codesToStates.put(State.OK.getCode(), State.OK);
            codesToStates.put(State.OR.getCode(), State.OR);
            codesToStates.put(State.PA.getCode(), State.PA);
            codesToStates.put(State.RI.getCode(), State.RI);
            codesToStates.put(State.SC.getCode(), State.SC);
            codesToStates.put(State.SD.getCode(), State.SD);
            codesToStates.put(State.TN.getCode(), State.TN);
            codesToStates.put(State.TX.getCode(), State.TX);
            codesToStates.put(State.UT.getCode(), State.UT);
            codesToStates.put(State.VA.getCode(), State.VA);
            codesToStates.put(State.VT.getCode(), State.VT);
            codesToStates.put(State.WA.getCode(), State.WA);
            codesToStates.put(State.WI.getCode(), State.WI);
            codesToStates.put(State.WV.getCode(), State.WV);
            codesToStates.put(State.WY.getCode(), State.WY);

            namesToStates.put(State.AK.getName(), State.AK);
            namesToStates.put(State.AL.getName(), State.AL);
            namesToStates.put(State.AR.getName(), State.AR);
            namesToStates.put(State.AZ.getName(), State.AZ);
            namesToStates.put(State.CA.getName(), State.CA);
            namesToStates.put(State.CO.getName(), State.CO);
            namesToStates.put(State.CT.getName(), State.CT);
            namesToStates.put(State.DC.getName(), State.DC);
            namesToStates.put(State.DE.getName(), State.DE);
            namesToStates.put(State.FL.getName(), State.FL);
            namesToStates.put(State.GA.getName(), State.GA);
            namesToStates.put(State.HI.getName(), State.HI);
            namesToStates.put(State.IA.getName(), State.IA);
            namesToStates.put(State.ID.getName(), State.ID);
            namesToStates.put(State.IL.getName(), State.IL);
            namesToStates.put(State.IN.getName(), State.IN);
            namesToStates.put(State.KS.getName(), State.KS);
            namesToStates.put(State.KY.getName(), State.KY);
            namesToStates.put(State.LA.getName(), State.LA);
            namesToStates.put(State.MA.getName(), State.MA);
            namesToStates.put(State.MD.getName(), State.MD);
            namesToStates.put(State.ME.getName(), State.ME);
            namesToStates.put(State.MI.getName(), State.MI);
            namesToStates.put(State.MN.getName(), State.MN);
            namesToStates.put(State.MO.getName(), State.MO);
            namesToStates.put(State.MS.getName(), State.MS);
            namesToStates.put(State.MT.getName(), State.MT);
            namesToStates.put(State.NC.getName(), State.NC);
            namesToStates.put(State.ND.getName(), State.ND);
            namesToStates.put(State.NE.getName(), State.NE);
            namesToStates.put(State.NH.getName(), State.NH);
            namesToStates.put(State.NJ.getName(), State.NJ);
            namesToStates.put(State.NM.getName(), State.NM);
            namesToStates.put(State.NV.getName(), State.NV);
            namesToStates.put(State.NY.getName(), State.NY);
            namesToStates.put(State.OH.getName(), State.OH);
            namesToStates.put(State.OK.getName(), State.OK);
            namesToStates.put(State.OR.getName(), State.OR);
            namesToStates.put(State.PA.getName(), State.PA);
            namesToStates.put(State.RI.getName(), State.RI);
            namesToStates.put(State.SC.getName(), State.SC);
            namesToStates.put(State.SD.getName(), State.SD);
            namesToStates.put(State.TN.getName(), State.TN);
            namesToStates.put(State.TX.getName(), State.TX);
            namesToStates.put(State.UT.getName(), State.UT);
            namesToStates.put(State.VA.getName(), State.VA);
            namesToStates.put(State.VT.getName(), State.VT);
            namesToStates.put(State.WA.getName(), State.WA);
            namesToStates.put(State.WI.getName(), State.WI);
            namesToStates.put(State.WV.getName(), State.WV);
            namesToStates.put(State.WY.getName(), State.WY);
        }
    }

     



  • TopCoder tests what (?) Speed of solving or just ability to solve? As in, difficult problems, like the ACM programming competitions?

    Because I participated in this Google CodeJam some 2 years back, it used TopCoder Arena thing. The problems were pretty average in difficulty and I placed 2nd out of 40 ppl in the room, solving all problems within half hour or something..... still didn't make the prelims :-\   Then I realized it was probably about speed...... who can code faster?
     



  • But think of the performance boost he gets, unrolling the loop instead of using an iterator! No doubt this class initializes at lightning speed on program startup.

    Another example of why premature optimization is the root of all evil... 



  • Well, parts of this code make sense if some complexity constraints had to be matched: 's =  State.NY;' is O(1), whilest 'codesToStates.get("NY");' is O(log n). Using a database in the contest might have been completly wrong. But I also do not get why initialization was done that cumbersome. Instead of

         public static final State AK = new State("AK", "Alaska");

    it should have been:

        public static final State AK = createState("AK", "Alaska");

     
    where createState is this (using more sane collection names):

       protected static State createState(String code, String name) {
            final State s = new State(code, name);

            states.add(s);
            statesByCode.put(s.getCode(), s);
            statesByName.put(s.getName(), s);

            return s;
        }



  • I would have created the states list like this:

    CreateState("AlasKa");

    CreateState("ALabama");

    CreateState("ARkansas");

    CreateState("AriZona");

    That way I don't even have to enter the abreviations as a seperate string.



  • [quote user="nbit"]

    I would have created the states list like this:

    CreateState("AlasKa");

    CreateState("ALabama");

    CreateState("ARkansas");

    CreateState("AriZona");

    That way I don't even have to enter the abreviations as a seperate string.

    [/quote]

    You'd score a 3 here



  • [quote user="Astaedus"][quote user="nbit"]

    I would have created the states list like this:

    CreateState("AlasKa");

    CreateState("ALabama");

    CreateState("ARkansas");

    CreateState("AriZona");

    That way I don't even have to enter the abreviations as a seperate string.

    [/quote]

    You'd score a 3 here

    [/quote]

    ROFL!  You would score a 2 for using that article.

     

    I think that part of the score you get on top coder has to do with speed.  If so, the coder here might have used a code generation utility to write out the code rather than thinking about the most effective/shortest way to write it. 



  • TopCoder tests: 

    1) Write code that works.  If your code does not survive the unit tests after programming is over, you get 0 points, no matter how quickly you submitted it.  In addition, if any other programmer can submit a unit test where your code does not work, you get 0 points.

    2) Write code that is not absolutely dead at performance.  If your code exceeds some predetermined timeout, that counts as failing a unit test.  However, inside of that, it doesn't matter if your code takes 1 second or 10 seconds. 

    3) Time to write.  Assuming your code does work and passes all the unit tests, the higher score goes to the person who submitted first.

    Other factors, such as efficiency of the code, maintainability of the code, wtfness of the code, etc, are irrelevant.  To win at TopCoder, you have to be able to write working code fast.  However, it's not required that you write *good* code.



  • OK, so the namesToStates and statesToNames seems a bit brain dead, but not quite WTF worthy.  The whole idea of using a database during a Topcoder competition is the "real WTF™".

     In a Topcoder competition you basically are given an interface to code to, and you submit a single class that solves the problem.  I'm

    thinking the OP is just jealous because this guy beat him in the competition ;)
     



  • [quote user="smbell"]

    OK, so the namesToStates and statesToNames seems a bit brain dead, but not quite WTF worthy.  The whole idea of using a database during a Topcoder competition is the "real WTF™".

     In a Topcoder competition you basically are given an interface to code to, and you submit a single class that solves the problem.  I'm

    thinking the OP is just jealous because this guy beat him in the competition ;)
     

    [/quote]

     

    The code presented was not part of any TopCoder competition, the author (not the OP) just lets everyone know that he won a TopCoder competition.  The code presented was in use on a production system.



  • Seems this code could benefit from some VOP  :)



  • [quote user="mleh"][quote user="smbell"]

    OK, so the namesToStates and statesToNames seems a bit brain dead, but not quite WTF worthy.  The whole idea of using a database during a Topcoder competition is the "real WTF™".

     In a Topcoder competition you basically are given an interface to code to, and you submit a single class that solves the problem.  I'm

    thinking the OP is just jealous because this guy beat him in the competition ;)
     

    [/quote]

     

    The code presented was not part of any TopCoder competition, the author (not the OP) just lets everyone know that he won a TopCoder competition.  The code presented was in use on a production system.

    [/quote]

     

    I completely missed that.  I was wondering how he had a public class that doesn't solve a problem as part of a Topcoder submission.  Nevermind then.  Nothing to see here (except maybe the BG girls mmmmm).



  • [quote user="Colin McGuigan"]Other factors, such as efficiency of the code, maintainability of the code, wtfness of the code, etc, are irrelevant.  To win at TopCoder, you have to be able to write working code fast.  However, it's not required that you write *good* code.[/quote]

    Their defintion of a top coder is quite different than mine.  Yes, good should be correct and pass all unit tests.  That would be very high on my list.  But to put quantity of code produced over maintainability?  To not even consider maintainability as a criteria for a TopCoder would completely invalidate the competition in my mind.  I'd rather a developer spend the extra time writing maintainable code now than for me to have to spend twice as much time in the future trying to fix/rewrite it.

     I worked with one developer at a company who had a reputation as being a wonder developer.  He was acquired during a merger, and was the other company's number one guy.  He was famous for pumping out working code quickly.  It worked, as long as you stayed within the original specifications and didn't want to do anything else with it.  Only need to had x amount of data?  Sure, it will work.  Need x + 1?  Crash, or infinite loop, or spikes the CPU, or whatever.  Extendable?  Nope.  Maintainable?  Nope.

    He was probably the worst developer I've worked with, if only because of the huge mountains of crappy code he could produce.
     



  • Shouldn't it be "FastCoder" or "SpeedCoder" not "TopCoder"?



  •  

    Uhm... What about the GOOD way:

    public enum  State {
        AR("Arkansas"),
        CA("California"),
        ...
        WV("West Virginia")
        ;  

        private final static Map<String, State> namesToStates = new HashMap<String, State>(50);
        public final name;
        State(String name) {
           this.name = name;
           namesToStates.put(name, this);
        }

        public static State forName(String stateName) {
            return namesToStates.get(stateName);
        }

    :-) 

    Then you can call: 

    State.values() -> State[] = all the states
    State.valueOf("CA") -> State = State.California
    State.forName("California") -> State = State.California

    Benifits: All state objects are singleton (== comparison works). Less typing. Faster access. Free serialization. Easy data store integration. ONLY ONE MAP! 

     

     



  • Thanks, mleh, for clarifying that this code was not actually written at a TopCoder competition.  My only point in mentioning TopCoder was that I assumed those people were pretty sharp (I've never participated myself).  I think the comment that this contest has nothing to do with writing maintanable code is, sadly, very true.  
    Also, I hope that nbit was kidding.



  • [quote user="averagejoe"]Also, I hope that nbit was kidding.[/quote]

    We all do, Joe.  We all do.


Log in to reply