/* Subject: Contest submission for problem #1, file 1.java */ /* jeffpast@imail.EECS.Berkeley.EDU */ /* Wed Sep 17 22:43:05 PDT 2003 */ /*___CONTEST_SUBMISSION___ jeffpast 1 */ /* * P1.java * * Created on September 17, 2003, 1:41 PM */ import java.io.*; import java.util.*; /** * Time estimate: 2 hours * Actual time: 2:30 hours, most of which was spent wrestling with the inane Java API */ class P1 { /** Creates a new instance of P1 */ public P1() { } /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { StreamTokenizer t = new java.io.StreamTokenizer(new InputStreamReader(System.in)); LinkedList lines = new LinkedList(); int currentSet = 0; while (true) { t.nextToken(); //time to stop? if (t.ttype == t.TT_EOF) break; ClunkLine nextLine = new ClunkLine(); lines.add(nextLine); nextLine.lineNumber = (int)t.nval; //skip colon t.nextToken(); t.nextToken(); //get variable name or "If" if (t.sval.equals("if")) //we care about the case of "if" nextLine.ifStatement = true; else if (t.sval.equals("stop")) { lines.removeLast(); //analyze if (ExamineLines(lines)) System.out.println("Set " + currentSet + ": No use before definition"); else System.out.println("Set " + currentSet + ": Possible use before definition"); t.nextToken(); //discard ; lines.clear(); currentSet++; continue; //on to the next batch! } else { //variable name nextLine.ifStatement = false; nextLine.assignedVariable = t.sval; t.nextToken(); //discard = } t.nextToken(); //discard F t.nextToken(); //discard first ( t.nextToken(); //read in variables while (t.ttype != ')' ){ nextLine.variables.add(t.sval); t.nextToken(); if (t.ttype == ',') //comma t.nextToken(); } if (nextLine.ifStatement){ t.nextToken(); //discard goto t.nextToken(); //get dest line nextLine.branchToLineNumber = (int)t.nval; } t.nextToken(); //discard ; } System.exit(0); } //returns true if lines do not reference things that are undefined static boolean ExamineLines(LinkedList lines) { if (lines.isEmpty()) return true; //calculate all possible definition states ExploreStates(lines); Iterator i = lines.iterator(); while (i.hasNext()){ ClunkLine nextLine = (ClunkLine)i.next(); Iterator si = nextLine.possibleStates.iterator(); while (si.hasNext()){ TreeSet nextStates = (TreeSet)si.next(); if (!nextStates.containsAll(nextLine.variables)) return false; } if (nextLine.possibleStates.isEmpty()) { //first assignment; any variables? If so, we don't got 'em defined. if (!nextLine.variables.isEmpty()) { return false; } } } return true; } //Assumes: lines.count > 0 static void ExploreStates(LinkedList lines){ Hashtable lineTable = new Hashtable(); Iterator i; i = lines.iterator(); while (i.hasNext()){ //create a hash of all the lines to speed this up ClunkLine nextLine = (ClunkLine)i.next(); lineTable.put(new Integer(nextLine.lineNumber),nextLine); } int maxLineNumber = ((ClunkLine)lines.getLast()).lineNumber; boolean changing = true; //we'll loop til nothing stops a-changin' //(so deliciously inefficient) while (changing){ changing = false; i = lines.iterator(); while (i.hasNext()){ ClunkLine nextLine = (ClunkLine)i.next(); TreeSet newStates; if (!nextLine.ifStatement){ //make a deep copy of possibleStates with the new assigned variable added in newStates = new TreeSet(); Iterator li = nextLine.possibleStates.iterator(); while (li.hasNext()){ try { TreeSet newState = (TreeSet)((TreeSet)li.next()).clone(); newState.add(nextLine.assignedVariable); newStates.add ( newState ); } catch (Exception e) { } } //if there are no states (this is the first assignment seen), //we must start the ball rolling if (newStates.isEmpty()){ TreeSet baseSet = new TreeSet(); baseSet.add(nextLine.assignedVariable); newStates.add(baseSet); } if (nextLine.lineNumber != maxLineNumber){ ClunkLine followingLine = (ClunkLine)lineTable.get(new Integer(nextLine.lineNumber + 1)); changing |= followingLine.possibleStates.addAll(newStates); } } else { //if statement, no new states possible newStates = nextLine.possibleStates; if (nextLine.possibleStates.isEmpty()) newStates.add(new TreeSet()); if (nextLine.lineNumber != maxLineNumber){ ClunkLine followingLine = (ClunkLine)lineTable.get(new Integer(nextLine.lineNumber + 1)); changing |= followingLine.possibleStates.addAll(newStates); } if (nextLine.branchToLineNumber <= maxLineNumber){ ClunkLine followingLine = (ClunkLine)lineTable.get(new Integer(nextLine.branchToLineNumber)); changing |= followingLine.possibleStates.addAll(newStates); } } } } } } class ClunkLine { public int lineNumber; public boolean ifStatement; public LinkedList variables = new LinkedList(); public String assignedVariable; public int branchToLineNumber; public TreeSet possibleStates = new TreeSet(new dumbComparer()); } //All I can say in regards to why this class is needed is..."#$%@#ing Java!" class dumbComparer implements Comparator { public int compare(Object o1, Object o2) { TreeSet t1 = (TreeSet) o1; TreeSet t2 = (TreeSet) o2; if (t1.equals(t2)) return 0; return 1; } }